1// Copyright (c) 2012 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 <EGL/egl.h>
6
7#include "base/command_line.h"
8#include "gpu/command_buffer/client/gles2_lib.h"
9#include "gpu/gles2_conform_support/egl/display.h"
10#include "ui/gl/gl_context.h"
11#include "ui/gl/gl_surface.h"
12
13#if REGAL_STATIC_EGL
14extern "C" {
15
16typedef EGLContext RegalSystemContext;
17#define REGAL_DECL
18REGAL_DECL void RegalMakeCurrent( RegalSystemContext ctx );
19
20}  // extern "C"
21#endif
22
23namespace {
24void SetCurrentError(EGLint error_code) {
25}
26
27template<typename T>
28T EglError(EGLint error_code, T return_value) {
29  SetCurrentError(error_code);
30  return return_value;
31}
32
33template<typename T>
34T EglSuccess(T return_value) {
35  SetCurrentError(EGL_SUCCESS);
36  return return_value;
37}
38
39EGLint ValidateDisplay(EGLDisplay dpy) {
40  if (dpy == EGL_NO_DISPLAY)
41    return EGL_BAD_DISPLAY;
42
43  egl::Display* display = static_cast<egl::Display*>(dpy);
44  if (!display->is_initialized())
45    return EGL_NOT_INITIALIZED;
46
47  return EGL_SUCCESS;
48}
49
50EGLint ValidateDisplayConfig(EGLDisplay dpy, EGLConfig config) {
51  EGLint error_code = ValidateDisplay(dpy);
52  if (error_code != EGL_SUCCESS)
53    return error_code;
54
55  egl::Display* display = static_cast<egl::Display*>(dpy);
56  if (!display->IsValidConfig(config))
57    return EGL_BAD_CONFIG;
58
59  return EGL_SUCCESS;
60}
61
62EGLint ValidateDisplaySurface(EGLDisplay dpy, EGLSurface surface) {
63  EGLint error_code = ValidateDisplay(dpy);
64  if (error_code != EGL_SUCCESS)
65    return error_code;
66
67  egl::Display* display = static_cast<egl::Display*>(dpy);
68  if (!display->IsValidSurface(surface))
69    return EGL_BAD_SURFACE;
70
71  return EGL_SUCCESS;
72}
73
74EGLint ValidateDisplayContext(EGLDisplay dpy, EGLContext context) {
75  EGLint error_code = ValidateDisplay(dpy);
76  if (error_code != EGL_SUCCESS)
77    return error_code;
78
79  egl::Display* display = static_cast<egl::Display*>(dpy);
80  if (!display->IsValidContext(context))
81    return EGL_BAD_CONTEXT;
82
83  return EGL_SUCCESS;
84}
85}  // namespace
86
87extern "C" {
88EGLint eglGetError() {
89  // TODO(alokp): Fix me.
90  return EGL_SUCCESS;
91}
92
93EGLDisplay eglGetDisplay(EGLNativeDisplayType display_id) {
94  return new egl::Display(display_id);
95}
96
97EGLBoolean eglInitialize(EGLDisplay dpy, EGLint *major, EGLint *minor) {
98  if (dpy == EGL_NO_DISPLAY)
99    return EglError(EGL_BAD_DISPLAY, EGL_FALSE);
100
101  egl::Display* display = static_cast<egl::Display*>(dpy);
102  if (!display->Initialize())
103    return EglError(EGL_NOT_INITIALIZED, EGL_FALSE);
104
105  int argc = 1;
106  const char* const argv[] = {
107    "dummy"
108  };
109  CommandLine::Init(argc, argv);
110  gfx::GLSurface::InitializeOneOff();
111
112  *major = 1;
113  *minor = 4;
114  return EglSuccess(EGL_TRUE);
115}
116
117EGLBoolean eglTerminate(EGLDisplay dpy) {
118  EGLint error_code = ValidateDisplay(dpy);
119  if (error_code != EGL_SUCCESS)
120    return EglError(error_code, EGL_FALSE);
121
122  egl::Display* display = static_cast<egl::Display*>(dpy);
123  delete display;
124
125  return EglSuccess(EGL_TRUE);
126}
127
128const char* eglQueryString(EGLDisplay dpy, EGLint name) {
129  EGLint error_code = ValidateDisplay(dpy);
130  if (error_code != EGL_SUCCESS)
131    return EglError(error_code, static_cast<const char*>(NULL));
132
133  switch (name) {
134    case EGL_CLIENT_APIS:
135      return EglSuccess("OpenGL_ES");
136    case EGL_EXTENSIONS:
137      return EglSuccess("");
138    case EGL_VENDOR:
139      return EglSuccess("Google Inc.");
140    case EGL_VERSION:
141      return EglSuccess("1.4");
142    default:
143      return EglError(EGL_BAD_PARAMETER, static_cast<const char*>(NULL));
144  }
145}
146
147EGLBoolean eglChooseConfig(EGLDisplay dpy,
148                           const EGLint* attrib_list,
149                           EGLConfig* configs,
150                           EGLint config_size,
151                           EGLint* num_config) {
152  EGLint error_code = ValidateDisplay(dpy);
153  if (error_code != EGL_SUCCESS)
154    return EglError(error_code, EGL_FALSE);
155
156  if (num_config == NULL)
157    return EglError(EGL_BAD_PARAMETER, EGL_FALSE);
158
159  egl::Display* display = static_cast<egl::Display*>(dpy);
160  if (!display->ChooseConfigs(configs, config_size, num_config))
161    return EglError(EGL_BAD_ATTRIBUTE, EGL_FALSE);
162
163  return EglSuccess(EGL_TRUE);
164}
165
166EGLBoolean eglGetConfigs(EGLDisplay dpy,
167                         EGLConfig* configs,
168                         EGLint config_size,
169                         EGLint* num_config) {
170  EGLint error_code = ValidateDisplay(dpy);
171  if (error_code != EGL_SUCCESS)
172    return EglError(error_code, EGL_FALSE);
173
174  if (num_config == NULL)
175    return EglError(EGL_BAD_PARAMETER, EGL_FALSE);
176
177  egl::Display* display = static_cast<egl::Display*>(dpy);
178  if (!display->GetConfigs(configs, config_size, num_config))
179    return EglError(EGL_BAD_ATTRIBUTE, EGL_FALSE);
180
181  return EglSuccess(EGL_TRUE);
182}
183
184EGLBoolean eglGetConfigAttrib(EGLDisplay dpy,
185                              EGLConfig config,
186                              EGLint attribute,
187                              EGLint* value) {
188  EGLint error_code = ValidateDisplayConfig(dpy, config);
189  if (error_code != EGL_SUCCESS)
190    return EglError(error_code, EGL_FALSE);
191
192  egl::Display* display = static_cast<egl::Display*>(dpy);
193  if (!display->GetConfigAttrib(config, attribute, value))
194    return EglError(EGL_BAD_ATTRIBUTE, EGL_FALSE);
195
196  return EglSuccess(EGL_TRUE);
197}
198
199EGLSurface eglCreateWindowSurface(EGLDisplay dpy,
200                                  EGLConfig config,
201                                  EGLNativeWindowType win,
202                                  const EGLint* attrib_list) {
203  EGLint error_code = ValidateDisplayConfig(dpy, config);
204  if (error_code != EGL_SUCCESS)
205    return EglError(error_code, EGL_NO_SURFACE);
206
207  egl::Display* display = static_cast<egl::Display*>(dpy);
208  if (!display->IsValidNativeWindow(win))
209    return EglError(EGL_BAD_NATIVE_WINDOW, EGL_NO_SURFACE);
210
211  EGLSurface surface = display->CreateWindowSurface(config, win, attrib_list);
212  if (surface == EGL_NO_SURFACE)
213    return EglError(EGL_BAD_ALLOC, EGL_NO_SURFACE);
214
215  return EglSuccess(surface);
216}
217
218EGLSurface eglCreatePbufferSurface(EGLDisplay dpy,
219                                   EGLConfig config,
220                                   const EGLint* attrib_list) {
221  return EGL_NO_SURFACE;
222}
223
224EGLSurface eglCreatePixmapSurface(EGLDisplay dpy,
225                                  EGLConfig config,
226                                  EGLNativePixmapType pixmap,
227                                  const EGLint* attrib_list) {
228  return EGL_NO_SURFACE;
229}
230
231EGLBoolean eglDestroySurface(EGLDisplay dpy,
232                             EGLSurface surface) {
233  EGLint error_code = ValidateDisplaySurface(dpy, surface);
234  if (error_code != EGL_SUCCESS)
235    return EglError(error_code, EGL_FALSE);
236
237  egl::Display* display = static_cast<egl::Display*>(dpy);
238  display->DestroySurface(surface);
239  return EglSuccess(EGL_TRUE);
240}
241
242EGLBoolean eglQuerySurface(EGLDisplay dpy,
243                           EGLSurface surface,
244                           EGLint attribute,
245                           EGLint* value) {
246  return EGL_FALSE;
247}
248
249EGLBoolean eglBindAPI(EGLenum api) {
250  return EGL_FALSE;
251}
252
253EGLenum eglQueryAPI() {
254  return EGL_OPENGL_ES_API;
255}
256
257EGLBoolean eglWaitClient(void) {
258  return EGL_FALSE;
259}
260
261EGLBoolean eglReleaseThread(void) {
262  return EGL_FALSE;
263}
264
265EGLSurface eglCreatePbufferFromClientBuffer(EGLDisplay dpy,
266                                            EGLenum buftype,
267                                            EGLClientBuffer buffer,
268                                            EGLConfig config,
269                                            const EGLint* attrib_list) {
270  return EGL_NO_SURFACE;
271}
272
273EGLBoolean eglSurfaceAttrib(EGLDisplay dpy,
274                            EGLSurface surface,
275                            EGLint attribute,
276                            EGLint value) {
277  return EGL_FALSE;
278}
279
280EGLBoolean eglBindTexImage(EGLDisplay dpy,
281                           EGLSurface surface,
282                           EGLint buffer) {
283  return EGL_FALSE;
284}
285
286EGLBoolean eglReleaseTexImage(EGLDisplay dpy,
287                              EGLSurface surface,
288                              EGLint buffer) {
289  return EGL_FALSE;
290}
291
292EGLBoolean eglSwapInterval(EGLDisplay dpy, EGLint interval) {
293  return EGL_FALSE;
294}
295
296EGLContext eglCreateContext(EGLDisplay dpy,
297                            EGLConfig config,
298                            EGLContext share_context,
299                            const EGLint* attrib_list) {
300  EGLint error_code = ValidateDisplayConfig(dpy, config);
301  if (error_code != EGL_SUCCESS)
302    return EglError(error_code, EGL_NO_CONTEXT);
303
304  if (share_context != EGL_NO_CONTEXT) {
305    error_code = ValidateDisplayContext(dpy, share_context);
306    if (error_code != EGL_SUCCESS)
307      return EglError(error_code, EGL_NO_CONTEXT);
308  }
309
310  egl::Display* display = static_cast<egl::Display*>(dpy);
311  EGLContext context = display->CreateContext(
312      config, share_context, attrib_list);
313  if (context == EGL_NO_CONTEXT)
314    return EglError(EGL_BAD_ALLOC, EGL_NO_CONTEXT);
315
316  return EglSuccess(context);
317}
318
319EGLBoolean eglDestroyContext(EGLDisplay dpy, EGLContext ctx) {
320  EGLint error_code = ValidateDisplayContext(dpy, ctx);
321  if (error_code != EGL_SUCCESS)
322    return EglError(error_code, EGL_FALSE);
323
324  egl::Display* display = static_cast<egl::Display*>(dpy);
325  display->DestroyContext(ctx);
326  return EGL_TRUE;
327}
328
329EGLBoolean eglMakeCurrent(EGLDisplay dpy,
330                          EGLSurface draw,
331                          EGLSurface read,
332                          EGLContext ctx) {
333  if (ctx != EGL_NO_CONTEXT) {
334    EGLint error_code = ValidateDisplaySurface(dpy, draw);
335    if (error_code != EGL_SUCCESS)
336      return EglError(error_code, EGL_FALSE);
337    error_code = ValidateDisplaySurface(dpy, read);
338    if (error_code != EGL_SUCCESS)
339      return EglError(error_code, EGL_FALSE);
340    error_code = ValidateDisplayContext(dpy, ctx);
341    if (error_code != EGL_SUCCESS)
342      return EglError(error_code, EGL_FALSE);
343  }
344
345  egl::Display* display = static_cast<egl::Display*>(dpy);
346  if (!display->MakeCurrent(draw, read, ctx))
347    return EglError(EGL_CONTEXT_LOST, EGL_FALSE);
348
349#if REGAL_STATIC_EGL
350  RegalMakeCurrent(ctx);
351#endif
352
353  return EGL_TRUE;
354}
355
356EGLContext eglGetCurrentContext() {
357  return EGL_NO_CONTEXT;
358}
359
360EGLSurface eglGetCurrentSurface(EGLint readdraw) {
361  return EGL_NO_SURFACE;
362}
363
364EGLDisplay eglGetCurrentDisplay() {
365  return EGL_NO_DISPLAY;
366}
367
368EGLBoolean eglQueryContext(EGLDisplay dpy,
369                           EGLContext ctx,
370                           EGLint attribute,
371                           EGLint* value) {
372  return EGL_FALSE;
373}
374
375EGLBoolean eglWaitGL() {
376  return EGL_FALSE;
377}
378
379EGLBoolean eglWaitNative(EGLint engine) {
380  return EGL_FALSE;
381}
382
383EGLBoolean eglSwapBuffers(EGLDisplay dpy, EGLSurface surface) {
384  EGLint error_code = ValidateDisplaySurface(dpy, surface);
385  if (error_code != EGL_SUCCESS)
386    return EglError(error_code, EGL_FALSE);
387
388  egl::Display* display = static_cast<egl::Display*>(dpy);
389  display->SwapBuffers(surface);
390  return EglSuccess(EGL_TRUE);
391}
392
393EGLBoolean eglCopyBuffers(EGLDisplay dpy,
394                          EGLSurface surface,
395                          EGLNativePixmapType target) {
396  return EGL_FALSE;
397}
398
399/* Now, define eglGetProcAddress using the generic function ptr. type */
400__eglMustCastToProperFunctionPointerType
401eglGetProcAddress(const char* procname) {
402  return gles2::GetGLFunctionPointer(procname);
403}
404}  // extern "C"
405