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