Edit

kc3-lang/angle/util/EGLWindow.cpp

Branch :

  • Show log

    Commit

  • Author : Jamie Madill
    Date : 2014-08-26 13:16:36
    Hash : 3757a5ae
    Message : Allow app to specify EGL Window extra parameters. Extra parameters include pixel bit sizes, swap interval and if we want multisampling. This gives parity between the tests and samples EGL creation options. BUG=angle:730 Change-Id: I68d619c2ea141794f0089456bb6bba3d3b1c2a07 Reviewed-on: https://chromium-review.googlesource.com/213296 Reviewed-by: Brandon Jones <bajones@chromium.org> Reviewed-by: Geoff Lang <geofflang@chromium.org> Tested-by: Jamie Madill <jmadill@chromium.org>

  • util/EGLWindow.cpp
  • //
    // Copyright (c) 2013 The ANGLE Project Authors. All rights reserved.
    // Use of this source code is governed by a BSD-style license that can be
    // found in the LICENSE file.
    //
    
    #include <cassert>
    
    #include "EGLWindow.h"
    #include "OSWindow.h"
    
    #ifdef _WIN32
    #include "win32/Win32Timer.h"
    #include "win32/Win32Window.h"
    #else
    #error unsupported OS.
    #endif
    
    EGLWindow::EGLWindow(size_t width, size_t height,
                         EGLint glesMajorVersion, EGLint requestedRenderer)
        : mSurface(EGL_NO_SURFACE),
          mContext(EGL_NO_CONTEXT),
          mDisplay(EGL_NO_DISPLAY),
          mClientVersion(glesMajorVersion),
          mRequestedRenderer(requestedRenderer),
          mWidth(width),
          mHeight(height),
          mRedBits(-1),
          mGreenBits(-1),
          mBlueBits(-1),
          mAlphaBits(-1),
          mDepthBits(-1),
          mStencilBits(-1),
          mMultisample(false),
          mSwapInterval(-1)
    {
    }
    
    EGLWindow::~EGLWindow()
    {
        destroyGL();
    }
    
    void EGLWindow::swap()
    {
        eglSwapBuffers(mDisplay, mSurface);
    }
    
    EGLConfig EGLWindow::getConfig() const
    {
        return mConfig;
    }
    
    EGLDisplay EGLWindow::getDisplay() const
    {
        return mDisplay;
    }
    
    EGLSurface EGLWindow::getSurface() const
    {
        return mSurface;
    }
    
    EGLContext EGLWindow::getContext() const
    {
        return mContext;
    }
    
    bool EGLWindow::initializeGL(const OSWindow *osWindow)
    {
        PFNEGLGETPLATFORMDISPLAYEXTPROC eglGetPlatformDisplayEXT = reinterpret_cast<PFNEGLGETPLATFORMDISPLAYEXTPROC>(eglGetProcAddress("eglGetPlatformDisplayEXT"));
        if (!eglGetPlatformDisplayEXT)
        {
            return false;
        }
    
        const EGLint displayAttributes[] =
        {
            EGL_PLATFORM_ANGLE_TYPE_ANGLE, mRequestedRenderer,
            EGL_NONE,
        };
    
        mDisplay = eglGetPlatformDisplayEXT(EGL_PLATFORM_ANGLE_ANGLE, osWindow->getNativeDisplay(), displayAttributes);
        if (mDisplay == EGL_NO_DISPLAY)
        {
            destroyGL();
            return false;
        }
    
        EGLint majorVersion, minorVersion;
        if (!eglInitialize(mDisplay, &majorVersion, &minorVersion))
        {
            destroyGL();
            return false;
        }
    
        eglBindAPI(EGL_OPENGL_ES_API);
        if (eglGetError() != EGL_SUCCESS)
        {
            destroyGL();
            return false;
        }
    
        const EGLint configAttributes[] =
        {
            EGL_RED_SIZE,       (mRedBits >= 0)     ? mRedBits     : EGL_DONT_CARE,
            EGL_GREEN_SIZE,     (mGreenBits >= 0)   ? mGreenBits   : EGL_DONT_CARE,
            EGL_BLUE_SIZE,      (mBlueBits >= 0)    ? mBlueBits    : EGL_DONT_CARE,
            EGL_ALPHA_SIZE,     (mAlphaBits >= 0)   ? mAlphaBits   : EGL_DONT_CARE,
            EGL_DEPTH_SIZE,     (mDepthBits >= 0)   ? mDepthBits   : EGL_DONT_CARE,
            EGL_STENCIL_SIZE,   (mStencilBits >= 0) ? mStencilBits : EGL_DONT_CARE,
            EGL_SAMPLE_BUFFERS, mMultisample ? 1 : 0,
            EGL_NONE
        };
    
        EGLint configCount;
        if (!eglChooseConfig(mDisplay, configAttributes, &mConfig, 1, &configCount) || (configCount != 1))
        {
            destroyGL();
            return false;
        }
    
        eglGetConfigAttrib(mDisplay, mConfig, EGL_RED_SIZE, &mRedBits);
        eglGetConfigAttrib(mDisplay, mConfig, EGL_GREEN_SIZE, &mGreenBits);
        eglGetConfigAttrib(mDisplay, mConfig, EGL_BLUE_SIZE, &mBlueBits);
        eglGetConfigAttrib(mDisplay, mConfig, EGL_ALPHA_SIZE, &mBlueBits);
        eglGetConfigAttrib(mDisplay, mConfig, EGL_DEPTH_SIZE, &mDepthBits);
        eglGetConfigAttrib(mDisplay, mConfig, EGL_STENCIL_SIZE, &mStencilBits);
    
        const EGLint surfaceAttributes[] =
        {
            EGL_POST_SUB_BUFFER_SUPPORTED_NV, EGL_TRUE,
            EGL_NONE, EGL_NONE,
        };
    
        mSurface = eglCreateWindowSurface(mDisplay, mConfig, osWindow->getNativeWindow(), surfaceAttributes);
        if (mSurface == EGL_NO_SURFACE)
        {
            eglGetError(); // Clear error and try again
            mSurface = eglCreateWindowSurface(mDisplay, mConfig, NULL, NULL);
        }
    
        if (eglGetError() != EGL_SUCCESS)
        {
            destroyGL();
            return false;
        }
    
        EGLint contextAttibutes[] =
        {
            EGL_CONTEXT_CLIENT_VERSION, mClientVersion,
            EGL_NONE
        };
    
        mContext = eglCreateContext(mDisplay, mConfig, NULL, contextAttibutes);
        if (eglGetError() != EGL_SUCCESS)
        {
            destroyGL();
            return false;
        }
    
        eglMakeCurrent(mDisplay, mSurface, mSurface, mContext);
        if (eglGetError() != EGL_SUCCESS)
        {
            destroyGL();
            return false;
        }
    
        if (mSwapInterval != -1)
        {
            eglSwapInterval(mDisplay, mSwapInterval);
        }
    
        return true;
    }
    
    void EGLWindow::destroyGL()
    {
        if (mSurface != EGL_NO_SURFACE)
        {
            assert(mDisplay != EGL_NO_DISPLAY);
            eglDestroySurface(mDisplay, mSurface);
            mSurface = EGL_NO_SURFACE;
        }
    
        if (mContext != EGL_NO_CONTEXT)
        {
            assert(mDisplay != EGL_NO_DISPLAY);
            eglDestroyContext(mDisplay, mContext);
            mContext = EGL_NO_CONTEXT;
        }
    
        if (mDisplay != EGL_NO_DISPLAY)
        {
            eglMakeCurrent(mDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
            eglTerminate(mDisplay);
            mDisplay = EGL_NO_DISPLAY;
        }
    }