| Index: ui/ozone/platform/egltest/ozone_platform_egltest.cc
|
| diff --git a/ui/ozone/platform/egltest/ozone_platform_egltest.cc b/ui/ozone/platform/egltest/ozone_platform_egltest.cc
|
| new file mode 100644
|
| index 0000000000000000000000000000000000000000..579aa683db89835a7dcc859423099677188bf8cf
|
| --- /dev/null
|
| +++ b/ui/ozone/platform/egltest/ozone_platform_egltest.cc
|
| @@ -0,0 +1,278 @@
|
| +// Copyright 2014 The Chromium Authors. All rights reserved.
|
| +// Use of this source code is governed by a BSD-style license that can be
|
| +// found in the LICENSE file.
|
| +
|
| +#include "ui/ozone/platform/egltest/ozone_platform_egltest.h"
|
| +
|
| +#include "base/command_line.h"
|
| +#include "base/environment.h"
|
| +#include "base/files/file_path.h"
|
| +#include "base/path_service.h"
|
| +#include "library_loaders/libeglplatform_shim.h"
|
| +#include "ui/base/cursor/ozone/cursor_factory_ozone.h"
|
| +#include "ui/events/ozone/evdev/event_factory_evdev.h"
|
| +#include "ui/gfx/ozone/impl/file_surface_factory.h"
|
| +#include "ui/gfx/ozone/surface_ozone_egl.h"
|
| +#include "ui/gfx/vsync_provider.h"
|
| +#include "ui/ozone/ime/input_method_context_factory_ozone.h"
|
| +#include "ui/ozone/ozone_platform.h"
|
| +#include "ui/ozone/ozone_switches.h"
|
| +
|
| +#if defined(OS_CHROMEOS)
|
| +#include "ui/ozone/common/chromeos/native_display_delegate_ozone.h"
|
| +#endif
|
| +
|
| +#include <EGL/egl.h>
|
| +
|
| +namespace ui {
|
| +
|
| +namespace {
|
| +
|
| +const char kEglplatformShim[] = "EGLPLATFORM_SHIM";
|
| +const char kEglplatformShimDefault[] = "libeglplatform_shim.so.1";
|
| +const char kDefaultEglSoname[] = "libEGL.so.1";
|
| +const char kDefaultGlesSoname[] = "libGLESv2.so.2";
|
| +
|
| +// Get the library soname to load.
|
| +std::string GetShimLibraryName() {
|
| + std::string library;
|
| + scoped_ptr<base::Environment> env(base::Environment::Create());
|
| + if (env->GetVar(kEglplatformShim, &library))
|
| + return library;
|
| + return kEglplatformShimDefault;
|
| +}
|
| +
|
| +// EGL surface wrapper for libeglplatform_shim.
|
| +//
|
| +// This just manages the native window lifetime using
|
| +// ShimGetNativeWindow & ShimReleaseNativeWindow.
|
| +class SurfaceOzoneEgltest : public gfx::SurfaceOzoneEGL {
|
| + public:
|
| + SurfaceOzoneEgltest(ShimNativeWindowId window_id,
|
| + LibeglplatformShimLoader* eglplatform_shim)
|
| + : eglplatform_shim_(eglplatform_shim) {
|
| + native_window_ = eglplatform_shim_->ShimGetNativeWindow(window_id);
|
| + }
|
| + virtual ~SurfaceOzoneEgltest() {
|
| + CHECK(eglplatform_shim_->ShimReleaseNativeWindow(native_window_));
|
| + }
|
| +
|
| + virtual intptr_t GetNativeWindow() OVERRIDE { return native_window_; }
|
| +
|
| + virtual bool ResizeNativeWindow(const gfx::Size& viewport_size) OVERRIDE {
|
| + return true;
|
| + }
|
| +
|
| + virtual scoped_ptr<gfx::VSyncProvider> CreateVSyncProvider() OVERRIDE {
|
| + return scoped_ptr<gfx::VSyncProvider>();
|
| + }
|
| +
|
| + private:
|
| + LibeglplatformShimLoader* eglplatform_shim_;
|
| + intptr_t native_window_;
|
| +};
|
| +
|
| +// EGL surface factory for libeglplatform_shim.
|
| +//
|
| +// This finds the right EGL/GLES2 libraries for loading, and creates
|
| +// a single native window via ShimCreateWindow for drawing
|
| +// into.
|
| +class SurfaceFactoryEgltest : public gfx::SurfaceFactoryOzone {
|
| + public:
|
| + SurfaceFactoryEgltest(LibeglplatformShimLoader* eglplatform_shim)
|
| + : eglplatform_shim_(eglplatform_shim), window_id_(SHIM_NO_WINDOW_ID) {}
|
| + virtual ~SurfaceFactoryEgltest() { DestroySingleWindow(); }
|
| +
|
| + // Create the window.
|
| + bool CreateSingleWindow();
|
| + void DestroySingleWindow();
|
| +
|
| + // SurfaceFactoryOzone:
|
| + virtual HardwareState InitializeHardware() OVERRIDE;
|
| + virtual void ShutdownHardware() OVERRIDE;
|
| + virtual intptr_t GetNativeDisplay() OVERRIDE;
|
| + virtual gfx::AcceleratedWidget GetAcceleratedWidget() OVERRIDE;
|
| + virtual scoped_ptr<gfx::SurfaceOzoneEGL> CreateEGLSurfaceForWidget(
|
| + gfx::AcceleratedWidget widget) OVERRIDE;
|
| + virtual const int32* GetEGLSurfaceProperties(
|
| + const int32* desired_list) OVERRIDE;
|
| + virtual bool LoadEGLGLES2Bindings(
|
| + AddGLLibraryCallback add_gl_library,
|
| + SetGLGetProcAddressProcCallback set_gl_get_proc_address) OVERRIDE;
|
| +
|
| + private:
|
| + LibeglplatformShimLoader* eglplatform_shim_;
|
| +
|
| + // TODO(spang): Remove once we have a windowing API. This limits to 1 window.
|
| + ShimNativeWindowId window_id_;
|
| +};
|
| +
|
| +bool SurfaceFactoryEgltest::CreateSingleWindow() {
|
| + window_id_ = eglplatform_shim_->ShimCreateWindow();
|
| + return (window_id_ != SHIM_NO_WINDOW_ID);
|
| +}
|
| +
|
| +void SurfaceFactoryEgltest::DestroySingleWindow() {
|
| + if (window_id_ != SHIM_NO_WINDOW_ID)
|
| + CHECK(eglplatform_shim_->ShimDestroyWindow(window_id_));
|
| +}
|
| +
|
| +SurfaceFactoryEgltest::HardwareState
|
| +SurfaceFactoryEgltest::InitializeHardware() {
|
| + return INITIALIZED;
|
| +}
|
| +
|
| +void SurfaceFactoryEgltest::ShutdownHardware() {
|
| +}
|
| +
|
| +intptr_t SurfaceFactoryEgltest::GetNativeDisplay() {
|
| + return eglplatform_shim_->ShimGetNativeDisplay();
|
| +}
|
| +
|
| +gfx::AcceleratedWidget SurfaceFactoryEgltest::GetAcceleratedWidget() {
|
| + if (window_id_ == SHIM_NO_WINDOW_ID && !CreateSingleWindow())
|
| + LOG(FATAL) << "failed to create window";
|
| + return window_id_;
|
| +}
|
| +
|
| +scoped_ptr<gfx::SurfaceOzoneEGL>
|
| +SurfaceFactoryEgltest::CreateEGLSurfaceForWidget(
|
| + gfx::AcceleratedWidget widget) {
|
| + return make_scoped_ptr<gfx::SurfaceOzoneEGL>(
|
| + new SurfaceOzoneEgltest(widget, eglplatform_shim_));
|
| +}
|
| +
|
| +bool SurfaceFactoryEgltest::LoadEGLGLES2Bindings(
|
| + AddGLLibraryCallback add_gl_library,
|
| + SetGLGetProcAddressProcCallback set_gl_get_proc_address) {
|
| + const char* egl_soname = eglplatform_shim_->ShimQueryString(SHIM_EGL_LIBRARY);
|
| + const char* gles_soname =
|
| + eglplatform_shim_->ShimQueryString(SHIM_GLES_LIBRARY);
|
| + if (!egl_soname)
|
| + egl_soname = kDefaultEglSoname;
|
| + if (!gles_soname)
|
| + gles_soname = kDefaultGlesSoname;
|
| +
|
| + base::NativeLibraryLoadError error;
|
| + base::NativeLibrary egl_library =
|
| + base::LoadNativeLibrary(base::FilePath(egl_soname), &error);
|
| + if (!egl_library) {
|
| + LOG(WARNING) << "Failed to load EGL library: " << error.ToString();
|
| + return false;
|
| + }
|
| +
|
| + base::NativeLibrary gles_library =
|
| + base::LoadNativeLibrary(base::FilePath(gles_soname), &error);
|
| + if (!gles_library) {
|
| + LOG(WARNING) << "Failed to load GLES library: " << error.ToString();
|
| + base::UnloadNativeLibrary(egl_library);
|
| + return false;
|
| + }
|
| +
|
| + GLGetProcAddressProc get_proc_address =
|
| + reinterpret_cast<GLGetProcAddressProc>(
|
| + base::GetFunctionPointerFromNativeLibrary(egl_library,
|
| + "eglGetProcAddress"));
|
| + if (!get_proc_address) {
|
| + LOG(ERROR) << "eglGetProcAddress not found.";
|
| + base::UnloadNativeLibrary(egl_library);
|
| + base::UnloadNativeLibrary(gles_library);
|
| + return false;
|
| + }
|
| +
|
| + set_gl_get_proc_address.Run(get_proc_address);
|
| + add_gl_library.Run(egl_library);
|
| + add_gl_library.Run(gles_library);
|
| + return true;
|
| +}
|
| +
|
| +const int32* SurfaceFactoryEgltest::GetEGLSurfaceProperties(
|
| + const int32* desired_list) {
|
| + static const int32 broken_props[] = {
|
| + EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT,
|
| + EGL_SURFACE_TYPE, EGL_WINDOW_BIT | EGL_PBUFFER_BIT,
|
| + EGL_NONE,
|
| + };
|
| + return broken_props;
|
| +}
|
| +
|
| +// Test platform for EGL.
|
| +//
|
| +// This is a tiny EGL-based platform. Creation of the native window is
|
| +// handled by a separate library called eglplatform_shim.so.1 because
|
| +// this itself is platform specific and we want to test out multiple
|
| +// hardware platforms.
|
| +class OzonePlatformEgltest : public OzonePlatform {
|
| + public:
|
| + OzonePlatformEgltest()
|
| + : surface_factory_ozone_(&eglplatform_shim_), shim_initialized_(false) {}
|
| + virtual ~OzonePlatformEgltest() {
|
| + if (shim_initialized_)
|
| + eglplatform_shim_.ShimTerminate();
|
| + }
|
| +
|
| + void LoadShim() {
|
| + std::string library = GetShimLibraryName();
|
| +
|
| + if (eglplatform_shim_.Load(library))
|
| + return;
|
| +
|
| + base::FilePath module_path;
|
| + if (!PathService::Get(base::DIR_MODULE, &module_path))
|
| + LOG(ERROR) << "failed to get DIR_MODULE from PathService";
|
| + base::FilePath library_path = module_path.Append(library);
|
| +
|
| + if (eglplatform_shim_.Load(library_path.value()))
|
| + return;
|
| +
|
| + LOG(FATAL) << "failed to load " << library;
|
| + }
|
| +
|
| + void Initialize() {
|
| + LoadShim();
|
| + shim_initialized_ = eglplatform_shim_.ShimInitialize();
|
| + }
|
| +
|
| + // OzonePlatform:
|
| + virtual gfx::SurfaceFactoryOzone* GetSurfaceFactoryOzone() OVERRIDE {
|
| + return &surface_factory_ozone_;
|
| + }
|
| + virtual EventFactoryOzone* GetEventFactoryOzone() OVERRIDE {
|
| + return &event_factory_ozone_;
|
| + }
|
| + virtual InputMethodContextFactoryOzone* GetInputMethodContextFactoryOzone()
|
| + OVERRIDE {
|
| + return &input_method_context_factory_ozone_;
|
| + }
|
| + virtual CursorFactoryOzone* GetCursorFactoryOzone() OVERRIDE {
|
| + return &cursor_factory_ozone_;
|
| + }
|
| +
|
| +#if defined(OS_CHROMEOS)
|
| + virtual scoped_ptr<NativeDisplayDelegate> CreateNativeDisplayDelegate()
|
| + OVERRIDE {
|
| + return scoped_ptr<NativeDisplayDelegate>(new NativeDisplayDelegateOzone());
|
| + }
|
| +#endif
|
| +
|
| + private:
|
| + LibeglplatformShimLoader eglplatform_shim_;
|
| + SurfaceFactoryEgltest surface_factory_ozone_;
|
| + EventFactoryEvdev event_factory_ozone_;
|
| + InputMethodContextFactoryOzone input_method_context_factory_ozone_;
|
| + CursorFactoryOzone cursor_factory_ozone_;
|
| +
|
| + bool shim_initialized_;
|
| +
|
| + DISALLOW_COPY_AND_ASSIGN(OzonePlatformEgltest);
|
| +};
|
| +
|
| +} // namespace
|
| +
|
| +OzonePlatform* CreateOzonePlatformEgltest() {
|
| + OzonePlatformEgltest* platform = new OzonePlatformEgltest;
|
| + platform->Initialize();
|
| + return platform;
|
| +}
|
| +
|
| +} // namespace ui
|
|
|