Commit e159717d by Geoff Lang Committed by Commit Bot

Filter EGL attributes before passing them to the native driver.

Adding extensions that are not native driver extensions would cause surface creation to fail. BUG=angleproject:1635 Change-Id: I2f683ee0560e463aa06f3ba92d0bf3f3d8c8927d Reviewed-on: https://chromium-review.googlesource.com/701602 Commit-Queue: Geoff Lang <geofflang@chromium.org> Reviewed-by: 's avatarYuly Novikov <ynovikov@chromium.org>
parent af143fef
......@@ -6,6 +6,8 @@
#include "libANGLE/AttributeMap.h"
#include "common/debug.h"
namespace egl
{
......@@ -23,12 +25,24 @@ bool AttributeMap::contains(EGLAttrib key) const
return (mAttributes.find(key) != mAttributes.end());
}
EGLAttrib AttributeMap::get(EGLAttrib key) const
{
auto iter = mAttributes.find(key);
ASSERT(iter != mAttributes.end());
return iter->second;
}
EGLAttrib AttributeMap::get(EGLAttrib key, EGLAttrib defaultValue) const
{
auto iter = mAttributes.find(key);
return (mAttributes.find(key) != mAttributes.end()) ? iter->second : defaultValue;
}
EGLint AttributeMap::getAsInt(EGLAttrib key) const
{
return static_cast<EGLint>(get(key));
}
EGLint AttributeMap::getAsInt(EGLAttrib key, EGLint defaultValue) const
{
return static_cast<EGLint>(get(key, static_cast<EGLAttrib>(defaultValue)));
......
......@@ -23,7 +23,9 @@ class AttributeMap final
void insert(EGLAttrib key, EGLAttrib value);
bool contains(EGLAttrib key) const;
EGLAttrib get(EGLAttrib key) const;
EGLAttrib get(EGLAttrib key, EGLAttrib defaultValue) const;
EGLint getAsInt(EGLAttrib key) const;
EGLint getAsInt(EGLAttrib key, EGLint defaultValue) const;
bool isEmpty() const;
std::vector<EGLint> toIntVector() const;
......
......@@ -26,14 +26,14 @@
namespace egl
{
SurfaceState::SurfaceState(const egl::Config *configIn)
: defaultFramebuffer(nullptr), config(configIn)
SurfaceState::SurfaceState(const egl::Config *configIn, const AttributeMap &attributesIn)
: defaultFramebuffer(nullptr), config(configIn), attributes(attributesIn)
{
}
Surface::Surface(EGLint surfaceType, const egl::Config *config, const AttributeMap &attributes)
: FramebufferAttachmentObject(),
mState(config),
mState(config, attributes),
mImplementation(nullptr),
mCurrentCount(0),
mDestroyed(false),
......
......@@ -14,6 +14,7 @@
#include <EGL/egl.h>
#include "common/angleutils.h"
#include "libANGLE/AttributeMap.h"
#include "libANGLE/Error.h"
#include "libANGLE/FramebufferAttachment.h"
#include "libANGLE/RefCountObject.h"
......@@ -33,16 +34,16 @@ class EGLImplFactory;
namespace egl
{
class AttributeMap;
class Display;
struct Config;
struct SurfaceState final : private angle::NonCopyable
{
SurfaceState(const egl::Config *configIn);
SurfaceState(const egl::Config *configIn, const AttributeMap &attributesIn);
gl::Framebuffer *defaultFramebuffer;
const egl::Config *config;
AttributeMap attributes;
};
class Surface : public gl::FramebufferAttachmentObject
......
......@@ -25,7 +25,7 @@ namespace
class MockSurfaceImpl : public rx::SurfaceImpl
{
public:
MockSurfaceImpl() : SurfaceImpl(mockState), mockState(nullptr) {}
MockSurfaceImpl() : SurfaceImpl(mockState), mockState(nullptr, egl::AttributeMap()) {}
virtual ~MockSurfaceImpl() { destructor(); }
MOCK_METHOD1(destroy, void(const egl::Display *));
......
......@@ -8,6 +8,8 @@
#include "libANGLE/renderer/gl/egl/DisplayEGL.h"
#include "libANGLE/renderer/gl/egl/egl_utils.h"
namespace rx
{
......@@ -48,7 +50,7 @@ egl::Error DisplayEGL::initializeContext(const egl::AttributeMap &eglAttributes)
static_assert(EGL_CONTEXT_MINOR_VERSION == EGL_CONTEXT_MINOR_VERSION_KHR,
"Minor Version define should match");
std::vector<std::vector<EGLint>> contextAttribLists;
std::vector<native_egl::AttributeVector> contextAttribLists;
if (eglVersion >= gl::Version(1, 5) || mEGL->hasExtension("EGL_KHR_create_context"))
{
if (initializeRequested)
......@@ -84,7 +86,7 @@ egl::Error DisplayEGL::initializeContext(const egl::AttributeMap &eglAttributes)
contextAttribLists.push_back({EGL_CONTEXT_CLIENT_VERSION, 2, EGL_NONE});
}
for (auto &attribList : contextAttribLists)
for (const auto &attribList : contextAttribLists)
{
mContext = mEGL->createContext(mConfig, EGL_NO_CONTEXT, attribList.data());
if (mContext != EGL_NO_CONTEXT)
......
......@@ -8,15 +8,17 @@
#include "libANGLE/renderer/gl/egl/PbufferSurfaceEGL.h"
#include "libANGLE/Surface.h"
#include "libANGLE/renderer/gl/egl/egl_utils.h"
namespace rx
{
PbufferSurfaceEGL::PbufferSurfaceEGL(const egl::SurfaceState &state,
const FunctionsEGL *egl,
EGLConfig config,
const std::vector<EGLint> &attribList,
RendererGL *renderer)
: SurfaceEGL(state, egl, config, attribList, renderer)
: SurfaceEGL(state, egl, config, renderer)
{
}
......@@ -26,7 +28,16 @@ PbufferSurfaceEGL::~PbufferSurfaceEGL()
egl::Error PbufferSurfaceEGL::initialize(const egl::Display *display)
{
mSurface = mEGL->createPbufferSurface(mConfig, mAttribList.data());
constexpr EGLint kForwardedPBufferSurfaceAttributes[] = {
EGL_WIDTH, EGL_HEIGHT, EGL_LARGEST_PBUFFER, EGL_TEXTURE_FORMAT,
EGL_TEXTURE_TARGET, EGL_MIPMAP_TEXTURE, EGL_VG_COLORSPACE, EGL_VG_ALPHA_FORMAT,
};
native_egl::AttributeVector nativeAttribs =
native_egl::TrimAttributeMap(mState.attributes, kForwardedPBufferSurfaceAttributes);
native_egl::FinalizeAttributeVector(&nativeAttribs);
mSurface = mEGL->createPbufferSurface(mConfig, nativeAttribs.data());
if (mSurface == EGL_NO_SURFACE)
{
return egl::Error(mEGL->getError(), "eglCreatePbufferSurface failed");
......
......@@ -23,7 +23,6 @@ class PbufferSurfaceEGL : public SurfaceEGL
PbufferSurfaceEGL(const egl::SurfaceState &state,
const FunctionsEGL *egl,
EGLConfig config,
const std::vector<EGLint> &attribList,
RendererGL *renderer);
~PbufferSurfaceEGL() override;
......
......@@ -16,12 +16,10 @@ namespace rx
SurfaceEGL::SurfaceEGL(const egl::SurfaceState &state,
const FunctionsEGL *egl,
EGLConfig config,
const std::vector<EGLint> &attribList,
RendererGL *renderer)
: SurfaceGL(state, renderer),
mEGL(egl),
mConfig(config),
mAttribList(attribList),
mSurface(EGL_NO_SURFACE)
{
}
......
......@@ -23,7 +23,6 @@ class SurfaceEGL : public SurfaceGL
SurfaceEGL(const egl::SurfaceState &state,
const FunctionsEGL *egl,
EGLConfig config,
const std::vector<EGLint> &attribList,
RendererGL *renderer);
~SurfaceEGL() override;
......@@ -48,7 +47,6 @@ class SurfaceEGL : public SurfaceGL
protected:
const FunctionsEGL *mEGL;
EGLConfig mConfig;
std::vector<EGLint> mAttribList;
EGLSurface mSurface;
};
......
......@@ -8,6 +8,9 @@
#include "libANGLE/renderer/gl/egl/WindowSurfaceEGL.h"
#include "libANGLE/Surface.h"
#include "libANGLE/renderer/gl/egl/egl_utils.h"
namespace rx
{
......@@ -15,9 +18,8 @@ WindowSurfaceEGL::WindowSurfaceEGL(const egl::SurfaceState &state,
const FunctionsEGL *egl,
EGLConfig config,
EGLNativeWindowType window,
const std::vector<EGLint> &attribList,
RendererGL *renderer)
: SurfaceEGL(state, egl, config, attribList, renderer), mWindow(window)
: SurfaceEGL(state, egl, config, renderer), mWindow(window)
{
}
......@@ -27,7 +29,15 @@ WindowSurfaceEGL::~WindowSurfaceEGL()
egl::Error WindowSurfaceEGL::initialize(const egl::Display *display)
{
mSurface = mEGL->createWindowSurface(mConfig, mWindow, mAttribList.data());
constexpr EGLint kForwardedWindowSurfaceAttributes[] = {
EGL_RENDER_BUFFER, EGL_POST_SUB_BUFFER_SUPPORTED_NV,
};
native_egl::AttributeVector nativeAttribs =
native_egl::TrimAttributeMap(mState.attributes, kForwardedWindowSurfaceAttributes);
native_egl::FinalizeAttributeVector(&nativeAttribs);
mSurface = mEGL->createWindowSurface(mConfig, mWindow, nativeAttribs.data());
if (mSurface == EGL_NO_SURFACE)
{
return egl::Error(mEGL->getError(), "eglCreateWindowSurface failed");
......
......@@ -21,7 +21,6 @@ class WindowSurfaceEGL : public SurfaceEGL
const FunctionsEGL *egl,
EGLConfig config,
EGLNativeWindowType window,
const std::vector<EGLint> &attribList,
RendererGL *renderer);
~WindowSurfaceEGL() override;
......
......@@ -175,7 +175,7 @@ SurfaceImpl *DisplayAndroid::createWindowSurface(const egl::SurfaceState &state,
success = mEGL->chooseConfig(configAttribList, &config, 1, &numConfig);
ASSERT(success && numConfig == 1);
return new WindowSurfaceEGL(state, mEGL, config, window, attribs.toIntVector(), getRenderer());
return new WindowSurfaceEGL(state, mEGL, config, window, getRenderer());
}
SurfaceImpl *DisplayAndroid::createPbufferSurface(const egl::SurfaceState &state,
......@@ -189,7 +189,7 @@ SurfaceImpl *DisplayAndroid::createPbufferSurface(const egl::SurfaceState &state
success = mEGL->chooseConfig(configAttribList, &config, 1, &numConfig);
ASSERT(success && numConfig == 1);
return new PbufferSurfaceEGL(state, mEGL, config, attribs.toIntVector(), getRenderer());
return new PbufferSurfaceEGL(state, mEGL, config, getRenderer());
}
SurfaceImpl *DisplayAndroid::createPbufferFromClientBuffer(const egl::SurfaceState &state,
......
//
// Copyright (c) 2017 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.
//
// egl_utils.cpp: Utility routines specific to the EGL->EGL implementation.
#include "libANGLE/renderer/gl/egl/egl_utils.h"
#include "common/debug.h"
namespace rx
{
namespace native_egl
{
AttributeVector TrimAttributeMap(const egl::AttributeMap &attributes,
const EGLint *forwardAttribs,
size_t forwardAttribsCount)
{
AttributeVector result;
for (size_t forwardAttribIndex = 0; forwardAttribIndex < forwardAttribsCount;
forwardAttribIndex++)
{
EGLint forwardAttrib = forwardAttribs[forwardAttribIndex];
if (attributes.contains(forwardAttrib))
{
result.push_back(forwardAttrib);
result.push_back(attributes.get(forwardAttrib));
}
}
return result;
}
void FinalizeAttributeVector(AttributeVector *attributeVector)
{
ASSERT(attributeVector);
attributeVector->push_back(EGL_NONE);
}
} // namespace egl
} // namespace rx
//
// Copyright (c) 2017 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.
//
// egl_utils.h: Utility routines specific to the EGL->EGL implementation.
#ifndef LIBANGLE_RENDERER_GL_EGL_EGLUTILS_H_
#define LIBANGLE_RENDERER_GL_EGL_EGLUTILS_H_
#include <vector>
#include "common/platform.h"
#include "libANGLE/AttributeMap.h"
namespace rx
{
namespace native_egl
{
using AttributeVector = std::vector<EGLint>;
// Filter the attribute map and return a vector of attributes that can be passed to the native
// driver. Does NOT append EGL_NONE to the vector.
AttributeVector TrimAttributeMap(const egl::AttributeMap &attributes,
const EGLint *forwardAttribs,
size_t forwardAttribsCount);
template <size_t N>
AttributeVector TrimAttributeMap(const egl::AttributeMap &attributes,
const EGLint (&forwardAttribs)[N])
{
return TrimAttributeMap(attributes, forwardAttribs, N);
}
// Append EGL_NONE to the attribute vector so that it can be passed to a native driver.
void FinalizeAttributeVector(AttributeVector *attributeVector);
} // namespace egl
} // namespace rx
#endif // LIBANGLE_RENDERER_GL_EGL_EGLUTILS_H_
......@@ -653,6 +653,8 @@
[
'libANGLE/renderer/gl/egl/DisplayEGL.cpp',
'libANGLE/renderer/gl/egl/DisplayEGL.h',
'libANGLE/renderer/gl/egl/egl_utils.cpp',
'libANGLE/renderer/gl/egl/egl_utils.h',
'libANGLE/renderer/gl/egl/FunctionsEGL.cpp',
'libANGLE/renderer/gl/egl/FunctionsEGL.h',
'libANGLE/renderer/gl/egl/functionsegl_typedefs.h',
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment