| Index: gpu/gles2_conform_support/egl/egl.cc
|
| diff --git a/gpu/gles2_conform_support/egl/egl.cc b/gpu/gles2_conform_support/egl/egl.cc
|
| index 0435067822ddbb3faf1d0eb097b8fcc57af96e1f..b14479bc3b944ae23809a3b8e3502d3d79f95d19 100644
|
| --- a/gpu/gles2_conform_support/egl/egl.cc
|
| +++ b/gpu/gles2_conform_support/egl/egl.cc
|
| @@ -5,186 +5,58 @@
|
| #include <EGL/egl.h>
|
| #include <stdint.h>
|
|
|
| -#include <memory>
|
| -
|
| -#include "base/command_line.h"
|
| -#include "base/environment.h"
|
| -#include "base/strings/string_split.h"
|
| -#include "base/strings/string_util.h"
|
| -#include "base/strings/utf_string_conversions.h"
|
| #include "gpu/command_buffer/client/gles2_lib.h"
|
| -#include "gpu/command_buffer/service/gpu_switches.h"
|
| -#include "gpu/config/gpu_info_collector.h"
|
| -#include "gpu/config/gpu_util.h"
|
| +#include "gpu/gles2_conform_support/egl/config.h"
|
| +#include "gpu/gles2_conform_support/egl/context.h"
|
| #include "gpu/gles2_conform_support/egl/display.h"
|
| -#include "ui/gl/gl_context.h"
|
| -#include "ui/gl/gl_surface.h"
|
| -
|
| -#if REGAL_STATIC_EGL
|
| -extern "C" {
|
| -
|
| -typedef EGLContext RegalSystemContext;
|
| -#define REGAL_DECL
|
| -REGAL_DECL void RegalMakeCurrent( RegalSystemContext ctx );
|
| -
|
| -} // extern "C"
|
| -#endif
|
| -
|
| -namespace {
|
| -void SetCurrentError(EGLint error_code) {
|
| -}
|
| -
|
| -template<typename T>
|
| -T EglError(EGLint error_code, T return_value) {
|
| - SetCurrentError(error_code);
|
| - return return_value;
|
| -}
|
| -
|
| -template<typename T>
|
| -T EglSuccess(T return_value) {
|
| - SetCurrentError(EGL_SUCCESS);
|
| - return return_value;
|
| -}
|
| -
|
| -EGLint ValidateDisplay(EGLDisplay dpy) {
|
| - if (dpy == EGL_NO_DISPLAY)
|
| - return EGL_BAD_DISPLAY;
|
| -
|
| - egl::Display* display = static_cast<egl::Display*>(dpy);
|
| - if (!display->is_initialized())
|
| - return EGL_NOT_INITIALIZED;
|
| -
|
| - return EGL_SUCCESS;
|
| -}
|
| -
|
| -EGLint ValidateDisplayConfig(EGLDisplay dpy, EGLConfig config) {
|
| - EGLint error_code = ValidateDisplay(dpy);
|
| - if (error_code != EGL_SUCCESS)
|
| - return error_code;
|
| -
|
| - egl::Display* display = static_cast<egl::Display*>(dpy);
|
| - if (!display->IsValidConfig(config))
|
| - return EGL_BAD_CONFIG;
|
| -
|
| - return EGL_SUCCESS;
|
| -}
|
| -
|
| -EGLint ValidateDisplaySurface(EGLDisplay dpy, EGLSurface surface) {
|
| - EGLint error_code = ValidateDisplay(dpy);
|
| - if (error_code != EGL_SUCCESS)
|
| - return error_code;
|
| -
|
| - egl::Display* display = static_cast<egl::Display*>(dpy);
|
| - if (!display->IsValidSurface(surface))
|
| - return EGL_BAD_SURFACE;
|
| -
|
| - return EGL_SUCCESS;
|
| -}
|
| -
|
| -EGLint ValidateDisplayContext(EGLDisplay dpy, EGLContext context) {
|
| - EGLint error_code = ValidateDisplay(dpy);
|
| - if (error_code != EGL_SUCCESS)
|
| - return error_code;
|
| -
|
| - egl::Display* display = static_cast<egl::Display*>(dpy);
|
| - if (!display->IsValidContext(context))
|
| - return EGL_BAD_CONTEXT;
|
| -
|
| - return EGL_SUCCESS;
|
| -}
|
| -} // namespace
|
| +#include "gpu/gles2_conform_support/egl/surface.h"
|
| +#include "gpu/gles2_conform_support/egl/thread_state.h"
|
|
|
| extern "C" {
|
| EGLAPI EGLint EGLAPIENTRY eglGetError() {
|
| - // TODO(alokp): Fix me.
|
| - return EGL_SUCCESS;
|
| + return egl::ThreadState::Get()->ConsumeErrorCode();
|
| }
|
|
|
| EGLAPI EGLDisplay EGLAPIENTRY eglGetDisplay(EGLNativeDisplayType display_id) {
|
| - return new egl::Display(display_id);
|
| + if (display_id != EGL_DEFAULT_DISPLAY)
|
| + return EGL_NO_DISPLAY;
|
| + return egl::ThreadState::Get()->GetDefaultDisplay();
|
| }
|
|
|
| EGLAPI EGLBoolean EGLAPIENTRY eglInitialize(EGLDisplay dpy,
|
| EGLint* major,
|
| EGLint* minor) {
|
| - if (dpy == EGL_NO_DISPLAY)
|
| - return EglError(EGL_BAD_DISPLAY, EGL_FALSE);
|
| -
|
| - egl::Display* display = static_cast<egl::Display*>(dpy);
|
| - if (!display->Initialize())
|
| - return EglError(EGL_NOT_INITIALIZED, EGL_FALSE);
|
| -
|
| - // eglInitialize can be called multiple times, prevent InitializeOneOff from
|
| - // being called multiple times.
|
| - if (gfx::GetGLImplementation() == gfx::kGLImplementationNone) {
|
| - base::CommandLine::StringVector argv;
|
| - std::unique_ptr<base::Environment> env(base::Environment::Create());
|
| - std::string env_string;
|
| - env->GetVar("CHROME_COMMAND_BUFFER_GLES2_ARGS", &env_string);
|
| -#if defined(OS_WIN)
|
| - argv = base::SplitString(base::UTF8ToUTF16(env_string),
|
| - base::kWhitespaceUTF16, base::TRIM_WHITESPACE,
|
| - base::SPLIT_WANT_NONEMPTY);
|
| - argv.insert(argv.begin(), base::UTF8ToUTF16("dummy"));
|
| -#else
|
| - argv = base::SplitString(env_string,
|
| - base::kWhitespaceASCII, base::TRIM_WHITESPACE,
|
| - base::SPLIT_WANT_NONEMPTY);
|
| - argv.insert(argv.begin(), "dummy");
|
| -#endif
|
| - base::CommandLine::Init(0, nullptr);
|
| - base::CommandLine* command_line = base::CommandLine::ForCurrentProcess();
|
| - // Need to call both Init and InitFromArgv, since Windows does not use
|
| - // argc, argv in CommandLine::Init(argc, argv).
|
| - command_line->InitFromArgv(argv);
|
| - if (!command_line->HasSwitch(switches::kDisableGpuDriverBugWorkarounds)) {
|
| - gpu::GPUInfo gpu_info;
|
| - gpu::CollectBasicGraphicsInfo(&gpu_info);
|
| - gpu::ApplyGpuDriverBugWorkarounds(gpu_info, command_line);
|
| - }
|
| -
|
| - gfx::GLSurface::InitializeOneOff();
|
| - }
|
| - if (major)
|
| - *major = 1;
|
| - if (minor)
|
| - *minor = 4;
|
| - return EglSuccess(EGL_TRUE);
|
| + egl::ThreadState* ts = egl::ThreadState::Get();
|
| + egl::Display* display = ts->GetDisplay(dpy);
|
| + if (!display)
|
| + return ts->ReturnError(EGL_BAD_DISPLAY, EGL_FALSE);
|
| + return display->Initialize(ts, major, minor);
|
| }
|
|
|
| EGLAPI EGLBoolean EGLAPIENTRY eglTerminate(EGLDisplay dpy) {
|
| - EGLint error_code = ValidateDisplay(dpy);
|
| - if (error_code != EGL_SUCCESS)
|
| - return EglError(error_code, EGL_FALSE);
|
| -
|
| - egl::Display* display = static_cast<egl::Display*>(dpy);
|
| - delete display;
|
| -
|
| - // TODO: EGL specifies that the objects are marked for deletion and they will
|
| - // remain alive as long as "contexts or surfaces associated with display is
|
| - // current to any thread".
|
| - // Currently we delete the display here, and may also call exit handlers.
|
| -
|
| - return EglSuccess(EGL_TRUE);
|
| + egl::ThreadState* ts = egl::ThreadState::Get();
|
| + egl::Display* display = ts->GetDisplay(dpy);
|
| + if (!display)
|
| + return ts->ReturnError(EGL_BAD_DISPLAY, EGL_FALSE);
|
| + return display->Terminate(ts);
|
| }
|
|
|
| EGLAPI const char* EGLAPIENTRY eglQueryString(EGLDisplay dpy, EGLint name) {
|
| - EGLint error_code = ValidateDisplay(dpy);
|
| - if (error_code != EGL_SUCCESS)
|
| - return EglError(error_code, static_cast<const char*>(NULL));
|
| -
|
| - switch (name) {
|
| - case EGL_CLIENT_APIS:
|
| - return EglSuccess("OpenGL_ES");
|
| - case EGL_EXTENSIONS:
|
| - return EglSuccess("");
|
| - case EGL_VENDOR:
|
| - return EglSuccess("Google Inc.");
|
| - case EGL_VERSION:
|
| - return EglSuccess("1.4");
|
| - default:
|
| - return EglError(EGL_BAD_PARAMETER, static_cast<const char*>(NULL));
|
| + egl::ThreadState* ts = egl::ThreadState::Get();
|
| + if (dpy == EGL_NO_DISPLAY) {
|
| + switch (name) {
|
| + case EGL_EXTENSIONS:
|
| + return ts->ReturnSuccess("");
|
| + case EGL_VERSION:
|
| + return ts->ReturnSuccess("1.4");
|
| + default:
|
| + break;
|
| + }
|
| }
|
| + egl::Display* display = ts->GetDisplay(dpy);
|
| + if (!display)
|
| + return ts->ReturnError<const char*>(EGL_BAD_DISPLAY, nullptr);
|
| + return display->QueryString(ts, name);
|
| }
|
|
|
| EGLAPI EGLBoolean EGLAPIENTRY eglChooseConfig(EGLDisplay dpy,
|
| @@ -192,103 +64,57 @@ EGLAPI EGLBoolean EGLAPIENTRY eglChooseConfig(EGLDisplay dpy,
|
| EGLConfig* configs,
|
| EGLint config_size,
|
| EGLint* num_config) {
|
| - EGLint error_code = ValidateDisplay(dpy);
|
| - if (error_code != EGL_SUCCESS)
|
| - return EglError(error_code, EGL_FALSE);
|
| -
|
| - if (num_config == NULL)
|
| - return EglError(EGL_BAD_PARAMETER, EGL_FALSE);
|
| -
|
| - egl::Display* display = static_cast<egl::Display*>(dpy);
|
| - if (!display->ChooseConfigs(configs, config_size, num_config))
|
| - return EglError(EGL_BAD_ATTRIBUTE, EGL_FALSE);
|
| -
|
| - return EglSuccess(EGL_TRUE);
|
| + egl::ThreadState* ts = egl::ThreadState::Get();
|
| + egl::Display* display = ts->GetDisplay(dpy);
|
| + if (!display)
|
| + return ts->ReturnError(EGL_BAD_DISPLAY, EGL_FALSE);
|
| + return display->ChooseConfig(ts, attrib_list, configs, config_size,
|
| + num_config);
|
| }
|
|
|
| EGLAPI EGLBoolean EGLAPIENTRY eglGetConfigs(EGLDisplay dpy,
|
| EGLConfig* configs,
|
| EGLint config_size,
|
| EGLint* num_config) {
|
| - EGLint error_code = ValidateDisplay(dpy);
|
| - if (error_code != EGL_SUCCESS)
|
| - return EglError(error_code, EGL_FALSE);
|
| -
|
| - if (num_config == NULL)
|
| - return EglError(EGL_BAD_PARAMETER, EGL_FALSE);
|
| -
|
| - egl::Display* display = static_cast<egl::Display*>(dpy);
|
| - if (!display->GetConfigs(configs, config_size, num_config))
|
| - return EglError(EGL_BAD_ATTRIBUTE, EGL_FALSE);
|
| -
|
| - return EglSuccess(EGL_TRUE);
|
| + egl::ThreadState* ts = egl::ThreadState::Get();
|
| + egl::Display* display = ts->GetDisplay(dpy);
|
| + if (!display)
|
| + return ts->ReturnError(EGL_BAD_DISPLAY, EGL_FALSE);
|
| + return display->GetConfigs(ts, configs, config_size, num_config);
|
| }
|
|
|
| EGLAPI EGLBoolean EGLAPIENTRY eglGetConfigAttrib(EGLDisplay dpy,
|
| - EGLConfig config,
|
| + EGLConfig cfg,
|
| EGLint attribute,
|
| EGLint* value) {
|
| - EGLint error_code = ValidateDisplayConfig(dpy, config);
|
| - if (error_code != EGL_SUCCESS)
|
| - return EglError(error_code, EGL_FALSE);
|
| -
|
| - egl::Display* display = static_cast<egl::Display*>(dpy);
|
| - if (!display->GetConfigAttrib(config, attribute, value))
|
| - return EglError(EGL_BAD_ATTRIBUTE, EGL_FALSE);
|
| -
|
| - return EglSuccess(EGL_TRUE);
|
| + egl::ThreadState* ts = egl::ThreadState::Get();
|
| + egl::Display* display = ts->GetDisplay(dpy);
|
| + if (!display)
|
| + return ts->ReturnError(EGL_BAD_DISPLAY, EGL_FALSE);
|
| + return display->GetConfigAttrib(ts, cfg, attribute, value);
|
| }
|
|
|
| EGLAPI EGLSurface EGLAPIENTRY
|
| eglCreateWindowSurface(EGLDisplay dpy,
|
| - EGLConfig config,
|
| + EGLConfig cfg,
|
| EGLNativeWindowType win,
|
| const EGLint* attrib_list) {
|
| - EGLint error_code = ValidateDisplayConfig(dpy, config);
|
| - if (error_code != EGL_SUCCESS)
|
| - return EglError(error_code, EGL_NO_SURFACE);
|
| -
|
| - egl::Display* display = static_cast<egl::Display*>(dpy);
|
| - if (!display->IsValidNativeWindow(win))
|
| - return EglError(EGL_BAD_NATIVE_WINDOW, EGL_NO_SURFACE);
|
| -
|
| - EGLSurface surface = display->CreateWindowSurface(config, win, attrib_list);
|
| - if (surface == EGL_NO_SURFACE)
|
| - return EglError(EGL_BAD_ALLOC, EGL_NO_SURFACE);
|
| -
|
| - return EglSuccess(surface);
|
| + egl::ThreadState* ts = egl::ThreadState::Get();
|
| + egl::Display* display = ts->GetDisplay(dpy);
|
| + if (!display)
|
| + return ts->ReturnError(EGL_BAD_DISPLAY, EGL_NO_SURFACE);
|
| + return display->CreateWindowSurface(ts, cfg, win, attrib_list);
|
| }
|
|
|
| EGLAPI EGLSurface EGLAPIENTRY
|
| eglCreatePbufferSurface(EGLDisplay dpy,
|
| - EGLConfig config,
|
| + EGLConfig cfg,
|
| const EGLint* attrib_list) {
|
| - EGLint error_code = ValidateDisplayConfig(dpy, config);
|
| - if (error_code != EGL_SUCCESS)
|
| - return EglError(error_code, EGL_NO_SURFACE);
|
| -
|
| - egl::Display* display = static_cast<egl::Display*>(dpy);
|
| - int width = 1;
|
| - int height = 1;
|
| - if (attrib_list) {
|
| - for (const int32_t* attr = attrib_list; attr[0] != EGL_NONE; attr += 2) {
|
| - switch (attr[0]) {
|
| - case EGL_WIDTH:
|
| - width = attr[1];
|
| - break;
|
| - case EGL_HEIGHT:
|
| - height = attr[1];
|
| - break;
|
| - }
|
| - }
|
| - }
|
| - display->SetCreateOffscreen(width, height);
|
| -
|
| - EGLSurface surface = display->CreateWindowSurface(config, 0, attrib_list);
|
| - if (surface == EGL_NO_SURFACE)
|
| - return EglError(EGL_BAD_ALLOC, EGL_NO_SURFACE);
|
| -
|
| - return EglSuccess(surface);
|
| + egl::ThreadState* ts = egl::ThreadState::Get();
|
| + egl::Display* display = ts->GetDisplay(dpy);
|
| + if (!display)
|
| + return ts->ReturnError(EGL_BAD_DISPLAY, EGL_NO_SURFACE);
|
| + return display->CreatePbufferSurface(ts, cfg, attrib_list);
|
| }
|
|
|
| EGLAPI EGLSurface EGLAPIENTRY
|
| @@ -300,14 +126,12 @@ eglCreatePixmapSurface(EGLDisplay dpy,
|
| }
|
|
|
| EGLAPI EGLBoolean EGLAPIENTRY eglDestroySurface(EGLDisplay dpy,
|
| - EGLSurface surface) {
|
| - EGLint error_code = ValidateDisplaySurface(dpy, surface);
|
| - if (error_code != EGL_SUCCESS)
|
| - return EglError(error_code, EGL_FALSE);
|
| -
|
| - egl::Display* display = static_cast<egl::Display*>(dpy);
|
| - display->DestroySurface(surface);
|
| - return EglSuccess(EGL_TRUE);
|
| + EGLSurface sfe) {
|
| + egl::ThreadState* ts = egl::ThreadState::Get();
|
| + egl::Display* display = ts->GetDisplay(dpy);
|
| + if (!display)
|
| + return ts->ReturnError(EGL_BAD_DISPLAY, EGL_FALSE);
|
| + return display->DestroySurface(ts, sfe);
|
| }
|
|
|
| EGLAPI EGLBoolean EGLAPIENTRY eglQuerySurface(EGLDisplay dpy,
|
| @@ -330,7 +154,8 @@ EGLAPI EGLBoolean EGLAPIENTRY eglWaitClient(void) {
|
| }
|
|
|
| EGLAPI EGLBoolean EGLAPIENTRY eglReleaseThread(void) {
|
| - return EGL_FALSE;
|
| + egl::ThreadState::ReleaseThread();
|
| + return EGL_TRUE;
|
| }
|
|
|
| EGLAPI EGLSurface EGLAPIENTRY
|
| @@ -366,64 +191,42 @@ EGLAPI EGLBoolean EGLAPIENTRY eglSwapInterval(EGLDisplay dpy, EGLint interval) {
|
| }
|
|
|
| EGLAPI EGLContext EGLAPIENTRY eglCreateContext(EGLDisplay dpy,
|
| - EGLConfig config,
|
| - EGLContext share_context,
|
| + EGLConfig cfg,
|
| + EGLContext share_ctx,
|
| const EGLint* attrib_list) {
|
| - EGLint error_code = ValidateDisplayConfig(dpy, config);
|
| - if (error_code != EGL_SUCCESS)
|
| - return EglError(error_code, EGL_NO_CONTEXT);
|
| -
|
| - if (share_context != EGL_NO_CONTEXT) {
|
| - error_code = ValidateDisplayContext(dpy, share_context);
|
| - if (error_code != EGL_SUCCESS)
|
| - return EglError(error_code, EGL_NO_CONTEXT);
|
| - }
|
| -
|
| - egl::Display* display = static_cast<egl::Display*>(dpy);
|
| - EGLContext context = display->CreateContext(
|
| - config, share_context, attrib_list);
|
| - if (context == EGL_NO_CONTEXT)
|
| - return EglError(EGL_BAD_ALLOC, EGL_NO_CONTEXT);
|
| -
|
| - return EglSuccess(context);
|
| + egl::ThreadState* ts = egl::ThreadState::Get();
|
| + egl::Display* display = ts->GetDisplay(dpy);
|
| + if (!display)
|
| + return ts->ReturnError(EGL_BAD_DISPLAY, EGL_NO_CONTEXT);
|
| + return display->CreateContext(ts, cfg, share_ctx, attrib_list);
|
| }
|
|
|
| EGLAPI EGLBoolean EGLAPIENTRY eglDestroyContext(EGLDisplay dpy,
|
| EGLContext ctx) {
|
| - EGLint error_code = ValidateDisplayContext(dpy, ctx);
|
| - if (error_code != EGL_SUCCESS)
|
| - return EglError(error_code, EGL_FALSE);
|
| -
|
| - egl::Display* display = static_cast<egl::Display*>(dpy);
|
| - display->DestroyContext(ctx);
|
| - return EGL_TRUE;
|
| + egl::ThreadState* ts = egl::ThreadState::Get();
|
| + egl::Display* display = ts->GetDisplay(dpy);
|
| + if (!display)
|
| + return ts->ReturnError(EGL_BAD_DISPLAY, EGL_FALSE);
|
| + return display->DestroyContext(ts, ctx);
|
| }
|
|
|
| EGLAPI EGLBoolean EGLAPIENTRY eglMakeCurrent(EGLDisplay dpy,
|
| EGLSurface draw,
|
| EGLSurface read,
|
| EGLContext ctx) {
|
| - if (ctx != EGL_NO_CONTEXT) {
|
| - EGLint error_code = ValidateDisplaySurface(dpy, draw);
|
| - if (error_code != EGL_SUCCESS)
|
| - return EglError(error_code, EGL_FALSE);
|
| - error_code = ValidateDisplaySurface(dpy, read);
|
| - if (error_code != EGL_SUCCESS)
|
| - return EglError(error_code, EGL_FALSE);
|
| - error_code = ValidateDisplayContext(dpy, ctx);
|
| - if (error_code != EGL_SUCCESS)
|
| - return EglError(error_code, EGL_FALSE);
|
| + egl::ThreadState* ts = egl::ThreadState::Get();
|
| + if (draw == EGL_NO_SURFACE && read == EGL_NO_SURFACE &&
|
| + ctx == EGL_NO_CONTEXT) {
|
| + egl::Display* display =
|
| + dpy == EGL_NO_DISPLAY ? ts->GetDefaultDisplay() : ts->GetDisplay(dpy);
|
| + if (!display)
|
| + return ts->ReturnError(EGL_BAD_DISPLAY, EGL_FALSE);
|
| + return display->ReleaseCurrent(ts);
|
| }
|
| -
|
| - egl::Display* display = static_cast<egl::Display*>(dpy);
|
| - if (!display->MakeCurrent(draw, read, ctx))
|
| - return EglError(EGL_CONTEXT_LOST, EGL_FALSE);
|
| -
|
| -#if REGAL_STATIC_EGL
|
| - RegalMakeCurrent(ctx);
|
| -#endif
|
| -
|
| - return EGL_TRUE;
|
| + egl::Display* display = ts->GetDisplay(dpy);
|
| + if (!display)
|
| + return ts->ReturnError(EGL_BAD_DISPLAY, EGL_FALSE);
|
| + return display->MakeCurrent(ts, draw, read, ctx);
|
| }
|
|
|
| EGLAPI EGLContext EGLAPIENTRY eglGetCurrentContext() {
|
| @@ -453,15 +256,12 @@ EGLAPI EGLBoolean EGLAPIENTRY eglWaitNative(EGLint engine) {
|
| return EGL_FALSE;
|
| }
|
|
|
| -EGLAPI EGLBoolean EGLAPIENTRY eglSwapBuffers(EGLDisplay dpy,
|
| - EGLSurface surface) {
|
| - EGLint error_code = ValidateDisplaySurface(dpy, surface);
|
| - if (error_code != EGL_SUCCESS)
|
| - return EglError(error_code, EGL_FALSE);
|
| -
|
| - egl::Display* display = static_cast<egl::Display*>(dpy);
|
| - display->SwapBuffers(surface);
|
| - return EglSuccess(EGL_TRUE);
|
| +EGLAPI EGLBoolean EGLAPIENTRY eglSwapBuffers(EGLDisplay dpy, EGLSurface sfe) {
|
| + egl::ThreadState* ts = egl::ThreadState::Get();
|
| + egl::Display* display = ts->GetDisplay(dpy);
|
| + if (!display)
|
| + return ts->ReturnError(EGL_BAD_DISPLAY, EGL_FALSE);
|
| + return display->SwapBuffers(ts, sfe);
|
| }
|
|
|
| EGLAPI EGLBoolean EGLAPIENTRY eglCopyBuffers(EGLDisplay dpy,
|
|
|