| Index: remoting/client/jni/egl_thread_context.cc
|
| diff --git a/remoting/client/jni/egl_thread_context.cc b/remoting/client/jni/egl_thread_context.cc
|
| index 53bf9c9b9ad6d26446b05bc47bbd46f2fed63145..928d79005dcff12f0fb3db7a16928393447c2af1 100644
|
| --- a/remoting/client/jni/egl_thread_context.cc
|
| +++ b/remoting/client/jni/egl_thread_context.cc
|
| @@ -14,29 +14,18 @@ EglThreadContext::EglThreadContext() {
|
| CHECK(eglGetCurrentContext() == EGL_NO_CONTEXT);
|
| display_ = eglGetDisplay(EGL_DEFAULT_DISPLAY);
|
| if (!display_ || !eglInitialize(display_, NULL, NULL)) {
|
| - LOG(FATAL) << "Failed to initialize EGL display.";
|
| + LOG(FATAL) << "Failed to initialize EGL display: " << eglGetError();
|
| }
|
|
|
| - const EGLint config_attribs[] = {
|
| - EGL_RED_SIZE, 8,
|
| - EGL_GREEN_SIZE, 8,
|
| - EGL_BLUE_SIZE, 8,
|
| - EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT,
|
| - EGL_NONE
|
| - };
|
| -
|
| - EGLint numConfigs;
|
| - if (!eglChooseConfig(display_, config_attribs, &config_, 1, &numConfigs)) {
|
| - LOG(FATAL) << "Failed to choose config.";
|
| - }
|
| - const EGLint context_attribs[] = {
|
| - EGL_CONTEXT_CLIENT_VERSION, 2,
|
| - EGL_NONE
|
| - };
|
| - context_ = eglCreateContext(display_, config_, EGL_NO_CONTEXT,
|
| - context_attribs);
|
| - if (!context_) {
|
| - LOG(FATAL) << "Failed to create context.";
|
| + if (CreateContextWithClientVersion(EGL_OPENGL_ES3_BIT, GlVersion::ES_3)) {
|
| + client_version_ = GlVersion::ES_3;
|
| + } else if (CreateContextWithClientVersion(EGL_OPENGL_ES2_BIT,
|
| + GlVersion::ES_2)) {
|
| + LOG(WARNING) << "OpenGL ES 3 context not supported."
|
| + << "Falled back to OpenGL ES 2";
|
| + client_version_ = GlVersion::ES_2;
|
| + } else {
|
| + LOG(FATAL) << "Failed to create context: " << eglGetError();
|
| }
|
| }
|
|
|
| @@ -59,13 +48,13 @@ void EglThreadContext::BindToWindow(EGLNativeWindowType window) {
|
| if (window) {
|
| surface_ = eglCreateWindowSurface(display_, config_, window, NULL);
|
| if (!surface_) {
|
| - LOG(FATAL) << "Failed to create window surface.";
|
| + LOG(FATAL) << "Failed to create window surface: " << eglGetError();
|
| }
|
| } else {
|
| surface_ = EGL_NO_SURFACE;
|
| }
|
| if (!eglMakeCurrent(display_, surface_, surface_, context_)) {
|
| - LOG(FATAL) << "Failed to make current.";
|
| + LOG(FATAL) << "Failed to make current: " << eglGetError();
|
| }
|
| }
|
|
|
| @@ -74,12 +63,46 @@ bool EglThreadContext::IsWindowBound() const {
|
| return surface_ != EGL_NO_SURFACE;
|
| }
|
|
|
| -void EglThreadContext::SwapBuffers() {
|
| +bool EglThreadContext::SwapBuffers() {
|
| DCHECK(thread_checker_.CalledOnValidThread());
|
| - DCHECK(IsWindowBound());
|
| + if (!IsWindowBound()) {
|
| + return false;
|
| + }
|
| if (!eglSwapBuffers(display_, surface_)) {
|
| - LOG(FATAL) << "Failed to swap buffer.";
|
| + // Not fatal since the surface may be destroyed on a different thread
|
| + // earlier than the window is unbound. The context can still be reused
|
| + // after rebinding to the right window.
|
| + LOG(WARNING) << "Failed to swap buffer: " << eglGetError();
|
| + return false;
|
| }
|
| + return true;
|
| +}
|
| +
|
| +bool EglThreadContext::CreateContextWithClientVersion(
|
| + int renderable_type,
|
| + GlVersion client_version) {
|
| + DCHECK(client_version != GlVersion::UNKNOWN);
|
| + EGLint config_attribs[] = {
|
| + EGL_RED_SIZE, 8,
|
| + EGL_GREEN_SIZE, 8,
|
| + EGL_BLUE_SIZE, 8,
|
| + EGL_RENDERABLE_TYPE, renderable_type,
|
| + EGL_NONE
|
| + };
|
| +
|
| + EGLint num_configs;
|
| + if (!eglChooseConfig(display_, config_attribs, &config_, 1, &num_configs)) {
|
| + LOG(WARNING) << "Failed to choose config: " << eglGetError();
|
| + return false;
|
| + }
|
| +
|
| + EGLint context_attribs[] = {
|
| + EGL_CONTEXT_CLIENT_VERSION, static_cast<int>(client_version),
|
| + EGL_NONE
|
| + };
|
| + context_ = eglCreateContext(display_, config_, EGL_NO_CONTEXT,
|
| + context_attribs);
|
| + return context_ != EGL_NO_CONTEXT;
|
| }
|
|
|
| } // namespace remoting
|
|
|