| 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 | 
|  |