1 // Copyright 2016 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.
4 
5 #include "ui/gl/init/gl_factory.h"
6 
7 #include "base/logging.h"
8 #include "base/trace_event/trace_event.h"
9 #include "ui/gl/gl_bindings.h"
10 #include "ui/gl/gl_context.h"
11 #include "ui/gl/gl_context_egl.h"
12 #include "ui/gl/gl_context_stub.h"
13 #include "ui/gl/gl_egl_api_implementation.h"
14 #include "ui/gl/gl_implementation.h"
15 #include "ui/gl/gl_share_group.h"
16 #include "ui/gl/gl_surface.h"
17 #include "ui/gl/gl_surface_egl.h"
18 #include "ui/gl/gl_surface_stub.h"
19 
20 namespace gl {
21 namespace init {
22 
23 namespace {
24 
25 // Used to render into an already current context+surface,
26 // that we do not have ownership of (draw callback).
27 // TODO(boliu): Make this inherit from GLContextEGL.
28 class GLNonOwnedContext : public GLContextReal {
29  public:
30   explicit GLNonOwnedContext(GLShareGroup* share_group);
31 
32   // Implement GLContext.
33   bool Initialize(GLSurface* compatible_surface,
34                   const GLContextAttribs& attribs) override;
35   bool MakeCurrent(GLSurface* surface) override;
ReleaseCurrent(GLSurface * surface)36   void ReleaseCurrent(GLSurface* surface) override {}
IsCurrent(GLSurface * surface)37   bool IsCurrent(GLSurface* surface) override { return true; }
GetHandle()38   void* GetHandle() override { return nullptr; }
39 
40  protected:
~GLNonOwnedContext()41   ~GLNonOwnedContext() override {}
42 
43  private:
44   EGLDisplay display_;
45 
46   DISALLOW_COPY_AND_ASSIGN(GLNonOwnedContext);
47 };
48 
GLNonOwnedContext(GLShareGroup * share_group)49 GLNonOwnedContext::GLNonOwnedContext(GLShareGroup* share_group)
50     : GLContextReal(share_group), display_(nullptr) {}
51 
Initialize(GLSurface * compatible_surface,const GLContextAttribs & attribs)52 bool GLNonOwnedContext::Initialize(GLSurface* compatible_surface,
53                                    const GLContextAttribs& attribs) {
54   display_ = eglGetDisplay(EGL_DEFAULT_DISPLAY);
55   return true;
56 }
57 
MakeCurrent(GLSurface * surface)58 bool GLNonOwnedContext::MakeCurrent(GLSurface* surface) {
59   BindGLApi();
60   SetCurrent(surface);
61   InitializeDynamicBindings();
62   return true;
63 }
64 
65 }  // namespace
66 
GetAllowedGLImplementations()67 std::vector<GLImplementation> GetAllowedGLImplementations() {
68   std::vector<GLImplementation> impls;
69   impls.push_back(kGLImplementationEGLGLES2);
70   impls.push_back(kGLImplementationEGLANGLE);
71   return impls;
72 }
73 
GetGLWindowSystemBindingInfo(const GLVersionInfo & gl_info,GLWindowSystemBindingInfo * info)74 bool GetGLWindowSystemBindingInfo(const GLVersionInfo& gl_info,
75                                   GLWindowSystemBindingInfo* info) {
76   switch (GetGLImplementation()) {
77     case kGLImplementationEGLGLES2:
78     case kGLImplementationEGLANGLE:
79       return GetGLWindowSystemBindingInfoEGL(info);
80     default:
81       return false;
82   }
83 }
84 
CreateGLContext(GLShareGroup * share_group,GLSurface * compatible_surface,const GLContextAttribs & attribs)85 scoped_refptr<GLContext> CreateGLContext(GLShareGroup* share_group,
86                                          GLSurface* compatible_surface,
87                                          const GLContextAttribs& attribs) {
88   TRACE_EVENT0("gpu", "gl::init::CreateGLContext");
89   switch (GetGLImplementation()) {
90     case kGLImplementationMockGL:
91       return scoped_refptr<GLContext>(new GLContextStub(share_group));
92     case kGLImplementationStubGL: {
93       scoped_refptr<GLContextStub> stub_context =
94           new GLContextStub(share_group);
95       stub_context->SetUseStubApi(true);
96       return stub_context;
97     }
98     case kGLImplementationDisabled:
99       NOTREACHED();
100       return nullptr;
101     default:
102       if (compatible_surface->GetHandle() ||
103           compatible_surface->IsSurfaceless()) {
104         return InitializeGLContext(new GLContextEGL(share_group),
105                                    compatible_surface, attribs);
106       } else {
107         return InitializeGLContext(new GLNonOwnedContext(share_group),
108                                    compatible_surface, attribs);
109       }
110   }
111 }
112 
CreateViewGLSurface(gfx::AcceleratedWidget window)113 scoped_refptr<GLSurface> CreateViewGLSurface(gfx::AcceleratedWidget window) {
114   TRACE_EVENT0("gpu", "gl::init::CreateViewGLSurface");
115   CHECK_NE(kGLImplementationNone, GetGLImplementation());
116   switch (GetGLImplementation()) {
117     case kGLImplementationEGLGLES2:
118     case kGLImplementationEGLANGLE:
119       if (window != gfx::kNullAcceleratedWidget) {
120         return InitializeGLSurface(new NativeViewGLSurfaceEGL(window, nullptr));
121       } else {
122         return InitializeGLSurface(new GLSurfaceStub());
123       }
124     default:
125       NOTREACHED();
126       return nullptr;
127   }
128 }
129 
CreateOffscreenGLSurfaceWithFormat(const gfx::Size & size,GLSurfaceFormat format)130 scoped_refptr<GLSurface> CreateOffscreenGLSurfaceWithFormat(
131     const gfx::Size& size, GLSurfaceFormat format) {
132   TRACE_EVENT0("gpu", "gl::init::CreateOffscreenGLSurface");
133   CHECK_NE(kGLImplementationNone, GetGLImplementation());
134   switch (GetGLImplementation()) {
135     case kGLImplementationEGLGLES2:
136     case kGLImplementationEGLANGLE: {
137       if (GLSurfaceEGL::IsEGLSurfacelessContextSupported() &&
138           (size.width() == 0 && size.height() == 0)) {
139         return InitializeGLSurfaceWithFormat(new SurfacelessEGL(size), format);
140       } else {
141         return InitializeGLSurfaceWithFormat(new PbufferGLSurfaceEGL(size),
142                                              format);
143       }
144     }
145     case kGLImplementationMockGL:
146     case kGLImplementationStubGL:
147       return new GLSurfaceStub;
148     default:
149       NOTREACHED();
150       return nullptr;
151   }
152 }
153 
SetDisabledExtensionsPlatform(const std::string & disabled_extensions)154 void SetDisabledExtensionsPlatform(const std::string& disabled_extensions) {
155   GLImplementation implementation = GetGLImplementation();
156   DCHECK_NE(kGLImplementationNone, implementation);
157   switch (implementation) {
158     case kGLImplementationEGLGLES2:
159     case kGLImplementationEGLANGLE:
160       SetDisabledExtensionsEGL(disabled_extensions);
161       break;
162     case kGLImplementationMockGL:
163     case kGLImplementationStubGL:
164       break;
165     default:
166       NOTREACHED();
167   }
168 }
169 
InitializeExtensionSettingsOneOffPlatform()170 bool InitializeExtensionSettingsOneOffPlatform() {
171   GLImplementation implementation = GetGLImplementation();
172   DCHECK_NE(kGLImplementationNone, implementation);
173   switch (implementation) {
174     case kGLImplementationEGLGLES2:
175     case kGLImplementationEGLANGLE:
176       return InitializeExtensionSettingsOneOffEGL();
177     case kGLImplementationMockGL:
178     case kGLImplementationStubGL:
179       return true;
180     default:
181       NOTREACHED();
182       return false;
183   }
184 }
185 
186 }  // namespace init
187 }  // namespace gl
188