15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved.
25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file.
45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/base_paths.h"
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/command_line.h"
72a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/files/file_path.h"
85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/logging.h"
95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/native_library.h"
105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/path_service.h"
115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/gl/gl_bindings.h"
125d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "ui/gl/gl_context_stub_with_extensions.h"
135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/gl/gl_egl_api_implementation.h"
145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/gl/gl_gl_api_implementation.h"
155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/gl/gl_implementation.h"
16a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "ui/gl/gl_implementation_osmesa.h"
175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/gl/gl_osmesa_api_implementation.h"
185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace gfx {
205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace {
225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void GL_BINDING_CALL MarshalClearDepthToClearDepthf(GLclampd depth) {
245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  glClearDepthf(static_cast<GLclampf>(depth));
255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void GL_BINDING_CALL MarshalDepthRangeToDepthRangef(GLclampd z_near,
285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                                    GLclampd z_far) {
295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  glDepthRangef(static_cast<GLclampf>(z_near), static_cast<GLclampf>(z_far));
305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace
335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void GetAllowedGLImplementations(std::vector<GLImplementation>* impls) {
355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  impls->push_back(kGLImplementationEGLGLES2);
36a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  impls->push_back(kGLImplementationOSMesaGL);
375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
395d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)bool InitializeStaticGLBindings(GLImplementation implementation) {
405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Prevent reinitialization with a different implementation. Once the gpu
415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // unit tests have initialized with kGLImplementationMock, we don't want to
425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // later switch to another GL implementation.
435d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  DCHECK_EQ(kGLImplementationNone, GetGLImplementation());
445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  switch (implementation) {
465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case kGLImplementationEGLGLES2: {
47010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)      base::NativeLibrary gles_library =
48010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)          LoadLibraryAndPrintError("libGLESv2.so");
49010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)      if (!gles_library)
505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        return false;
51010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)      base::NativeLibrary egl_library = LoadLibraryAndPrintError("libEGL.so");
525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      if (!egl_library) {
535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        base::UnloadNativeLibrary(gles_library);
545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        return false;
555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      }
565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      GLGetProcAddressProc get_proc_address =
585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          reinterpret_cast<GLGetProcAddressProc>(
595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              base::GetFunctionPointerFromNativeLibrary(
605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                  egl_library, "eglGetProcAddress"));
615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      if (!get_proc_address) {
625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        LOG(ERROR) << "eglGetProcAddress not found.";
635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        base::UnloadNativeLibrary(egl_library);
645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        base::UnloadNativeLibrary(gles_library);
655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        return false;
665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      }
675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      SetGLGetProcAddressProc(get_proc_address);
695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      AddGLNativeLibrary(egl_library);
705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      AddGLNativeLibrary(gles_library);
715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      SetGLImplementation(kGLImplementationEGLGLES2);
725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
735d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      InitializeStaticGLBindingsGL();
745d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      InitializeStaticGLBindingsEGL();
755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      // These two functions take single precision float rather than double
775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      // precision float parameters in GLES.
785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      ::gfx::g_driver_gl.fn.glClearDepthFn = MarshalClearDepthToClearDepthf;
795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      ::gfx::g_driver_gl.fn.glDepthRangeFn = MarshalDepthRangeToDepthRangef;
805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      break;
815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
82a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    case kGLImplementationOSMesaGL:
83a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      InitializeStaticGLBindingsOSMesaGL();
84a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      break;
855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case kGLImplementationMockGL: {
865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      SetGLImplementation(kGLImplementationMockGL);
875d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      InitializeStaticGLBindingsGL();
885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      break;
895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    default:
915d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      NOTIMPLEMENTED() << "InitializeStaticGLBindings on Android";
925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return false;
935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return true;
965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
985d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)bool InitializeDynamicGLBindings(GLImplementation implementation,
995d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                                 GLContext* context) {
1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  switch (implementation) {
1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case kGLImplementationEGLGLES2:
1025d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      InitializeDynamicGLBindingsGL(context);
1035d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      InitializeDynamicGLBindingsEGL(context);
1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      break;
105a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    case kGLImplementationOSMesaGL:
106a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      InitializeDynamicGLBindingsGL(context);
107a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      InitializeDynamicGLBindingsOSMESA(context);
108a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      break;
1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case kGLImplementationMockGL:
1105d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      if (!context) {
1115d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        scoped_refptr<GLContextStubWithExtensions> mock_context(
1125d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)            new GLContextStubWithExtensions());
1135d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        mock_context->SetGLVersionString("opengl es 3.0");
1145d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        InitializeDynamicGLBindingsGL(mock_context.get());
1155d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      } else
1165d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        InitializeDynamicGLBindingsGL(context);
1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      break;
1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    default:
1195d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      NOTREACHED() << "InitializeDynamicGLBindings on Android";
1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return false;
1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return true;
1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void InitializeDebugGLBindings() {
1275d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  InitializeDebugGLBindingsEGL();
1285d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  InitializeDebugGLBindingsGL();
129a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  InitializeDebugGLBindingsOSMESA();
1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ClearGLBindings() {
1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ClearGLBindingsEGL();
1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ClearGLBindingsGL();
135a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  ClearGLBindingsOSMESA();
1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SetGLImplementation(kGLImplementationNone);
1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  UnloadGLNativeLibraries();
1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
141868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)bool GetGLWindowSystemBindingInfo(GLWindowSystemBindingInfo* info) {
142868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  switch (GetGLImplementation()) {
143868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    case kGLImplementationEGLGLES2:
144868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      return GetGLWindowSystemBindingInfoEGL(info);
145868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    default:
146868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      return false;
147868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  }
148868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  return false;
149868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)}
150868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace gfx
152