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 @@ ...@@ -6,6 +6,8 @@
#include "libANGLE/AttributeMap.h" #include "libANGLE/AttributeMap.h"
#include "common/debug.h"
namespace egl namespace egl
{ {
...@@ -23,12 +25,24 @@ bool AttributeMap::contains(EGLAttrib key) const ...@@ -23,12 +25,24 @@ bool AttributeMap::contains(EGLAttrib key) const
return (mAttributes.find(key) != mAttributes.end()); 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 EGLAttrib AttributeMap::get(EGLAttrib key, EGLAttrib defaultValue) const
{ {
auto iter = mAttributes.find(key); auto iter = mAttributes.find(key);
return (mAttributes.find(key) != mAttributes.end()) ? iter->second : defaultValue; 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 EGLint AttributeMap::getAsInt(EGLAttrib key, EGLint defaultValue) const
{ {
return static_cast<EGLint>(get(key, static_cast<EGLAttrib>(defaultValue))); return static_cast<EGLint>(get(key, static_cast<EGLAttrib>(defaultValue)));
......
...@@ -23,7 +23,9 @@ class AttributeMap final ...@@ -23,7 +23,9 @@ class AttributeMap final
void insert(EGLAttrib key, EGLAttrib value); void insert(EGLAttrib key, EGLAttrib value);
bool contains(EGLAttrib key) const; bool contains(EGLAttrib key) const;
EGLAttrib get(EGLAttrib key) const;
EGLAttrib get(EGLAttrib key, EGLAttrib defaultValue) const; EGLAttrib get(EGLAttrib key, EGLAttrib defaultValue) const;
EGLint getAsInt(EGLAttrib key) const;
EGLint getAsInt(EGLAttrib key, EGLint defaultValue) const; EGLint getAsInt(EGLAttrib key, EGLint defaultValue) const;
bool isEmpty() const; bool isEmpty() const;
std::vector<EGLint> toIntVector() const; std::vector<EGLint> toIntVector() const;
......
...@@ -26,14 +26,14 @@ ...@@ -26,14 +26,14 @@
namespace egl namespace egl
{ {
SurfaceState::SurfaceState(const egl::Config *configIn) SurfaceState::SurfaceState(const egl::Config *configIn, const AttributeMap &attributesIn)
: defaultFramebuffer(nullptr), config(configIn) : defaultFramebuffer(nullptr), config(configIn), attributes(attributesIn)
{ {
} }
Surface::Surface(EGLint surfaceType, const egl::Config *config, const AttributeMap &attributes) Surface::Surface(EGLint surfaceType, const egl::Config *config, const AttributeMap &attributes)
: FramebufferAttachmentObject(), : FramebufferAttachmentObject(),
mState(config), mState(config, attributes),
mImplementation(nullptr), mImplementation(nullptr),
mCurrentCount(0), mCurrentCount(0),
mDestroyed(false), mDestroyed(false),
......
...@@ -14,6 +14,7 @@ ...@@ -14,6 +14,7 @@
#include <EGL/egl.h> #include <EGL/egl.h>
#include "common/angleutils.h" #include "common/angleutils.h"
#include "libANGLE/AttributeMap.h"
#include "libANGLE/Error.h" #include "libANGLE/Error.h"
#include "libANGLE/FramebufferAttachment.h" #include "libANGLE/FramebufferAttachment.h"
#include "libANGLE/RefCountObject.h" #include "libANGLE/RefCountObject.h"
...@@ -33,16 +34,16 @@ class EGLImplFactory; ...@@ -33,16 +34,16 @@ class EGLImplFactory;
namespace egl namespace egl
{ {
class AttributeMap;
class Display; class Display;
struct Config; struct Config;
struct SurfaceState final : private angle::NonCopyable struct SurfaceState final : private angle::NonCopyable
{ {
SurfaceState(const egl::Config *configIn); SurfaceState(const egl::Config *configIn, const AttributeMap &attributesIn);
gl::Framebuffer *defaultFramebuffer; gl::Framebuffer *defaultFramebuffer;
const egl::Config *config; const egl::Config *config;
AttributeMap attributes;
}; };
class Surface : public gl::FramebufferAttachmentObject class Surface : public gl::FramebufferAttachmentObject
......
...@@ -25,7 +25,7 @@ namespace ...@@ -25,7 +25,7 @@ namespace
class MockSurfaceImpl : public rx::SurfaceImpl class MockSurfaceImpl : public rx::SurfaceImpl
{ {
public: public:
MockSurfaceImpl() : SurfaceImpl(mockState), mockState(nullptr) {} MockSurfaceImpl() : SurfaceImpl(mockState), mockState(nullptr, egl::AttributeMap()) {}
virtual ~MockSurfaceImpl() { destructor(); } virtual ~MockSurfaceImpl() { destructor(); }
MOCK_METHOD1(destroy, void(const egl::Display *)); MOCK_METHOD1(destroy, void(const egl::Display *));
......
...@@ -8,6 +8,8 @@ ...@@ -8,6 +8,8 @@
#include "libANGLE/renderer/gl/egl/DisplayEGL.h" #include "libANGLE/renderer/gl/egl/DisplayEGL.h"
#include "libANGLE/renderer/gl/egl/egl_utils.h"
namespace rx namespace rx
{ {
...@@ -48,7 +50,7 @@ egl::Error DisplayEGL::initializeContext(const egl::AttributeMap &eglAttributes) ...@@ -48,7 +50,7 @@ egl::Error DisplayEGL::initializeContext(const egl::AttributeMap &eglAttributes)
static_assert(EGL_CONTEXT_MINOR_VERSION == EGL_CONTEXT_MINOR_VERSION_KHR, static_assert(EGL_CONTEXT_MINOR_VERSION == EGL_CONTEXT_MINOR_VERSION_KHR,
"Minor Version define should match"); "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 (eglVersion >= gl::Version(1, 5) || mEGL->hasExtension("EGL_KHR_create_context"))
{ {
if (initializeRequested) if (initializeRequested)
...@@ -84,7 +86,7 @@ egl::Error DisplayEGL::initializeContext(const egl::AttributeMap &eglAttributes) ...@@ -84,7 +86,7 @@ egl::Error DisplayEGL::initializeContext(const egl::AttributeMap &eglAttributes)
contextAttribLists.push_back({EGL_CONTEXT_CLIENT_VERSION, 2, EGL_NONE}); 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()); mContext = mEGL->createContext(mConfig, EGL_NO_CONTEXT, attribList.data());
if (mContext != EGL_NO_CONTEXT) if (mContext != EGL_NO_CONTEXT)
......
...@@ -8,15 +8,17 @@ ...@@ -8,15 +8,17 @@
#include "libANGLE/renderer/gl/egl/PbufferSurfaceEGL.h" #include "libANGLE/renderer/gl/egl/PbufferSurfaceEGL.h"
#include "libANGLE/Surface.h"
#include "libANGLE/renderer/gl/egl/egl_utils.h"
namespace rx namespace rx
{ {
PbufferSurfaceEGL::PbufferSurfaceEGL(const egl::SurfaceState &state, PbufferSurfaceEGL::PbufferSurfaceEGL(const egl::SurfaceState &state,
const FunctionsEGL *egl, const FunctionsEGL *egl,
EGLConfig config, EGLConfig config,
const std::vector<EGLint> &attribList,
RendererGL *renderer) RendererGL *renderer)
: SurfaceEGL(state, egl, config, attribList, renderer) : SurfaceEGL(state, egl, config, renderer)
{ {
} }
...@@ -26,7 +28,16 @@ PbufferSurfaceEGL::~PbufferSurfaceEGL() ...@@ -26,7 +28,16 @@ PbufferSurfaceEGL::~PbufferSurfaceEGL()
egl::Error PbufferSurfaceEGL::initialize(const egl::Display *display) 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) if (mSurface == EGL_NO_SURFACE)
{ {
return egl::Error(mEGL->getError(), "eglCreatePbufferSurface failed"); return egl::Error(mEGL->getError(), "eglCreatePbufferSurface failed");
......
...@@ -23,7 +23,6 @@ class PbufferSurfaceEGL : public SurfaceEGL ...@@ -23,7 +23,6 @@ class PbufferSurfaceEGL : public SurfaceEGL
PbufferSurfaceEGL(const egl::SurfaceState &state, PbufferSurfaceEGL(const egl::SurfaceState &state,
const FunctionsEGL *egl, const FunctionsEGL *egl,
EGLConfig config, EGLConfig config,
const std::vector<EGLint> &attribList,
RendererGL *renderer); RendererGL *renderer);
~PbufferSurfaceEGL() override; ~PbufferSurfaceEGL() override;
......
...@@ -16,12 +16,10 @@ namespace rx ...@@ -16,12 +16,10 @@ namespace rx
SurfaceEGL::SurfaceEGL(const egl::SurfaceState &state, SurfaceEGL::SurfaceEGL(const egl::SurfaceState &state,
const FunctionsEGL *egl, const FunctionsEGL *egl,
EGLConfig config, EGLConfig config,
const std::vector<EGLint> &attribList,
RendererGL *renderer) RendererGL *renderer)
: SurfaceGL(state, renderer), : SurfaceGL(state, renderer),
mEGL(egl), mEGL(egl),
mConfig(config), mConfig(config),
mAttribList(attribList),
mSurface(EGL_NO_SURFACE) mSurface(EGL_NO_SURFACE)
{ {
} }
......
...@@ -23,7 +23,6 @@ class SurfaceEGL : public SurfaceGL ...@@ -23,7 +23,6 @@ class SurfaceEGL : public SurfaceGL
SurfaceEGL(const egl::SurfaceState &state, SurfaceEGL(const egl::SurfaceState &state,
const FunctionsEGL *egl, const FunctionsEGL *egl,
EGLConfig config, EGLConfig config,
const std::vector<EGLint> &attribList,
RendererGL *renderer); RendererGL *renderer);
~SurfaceEGL() override; ~SurfaceEGL() override;
...@@ -48,7 +47,6 @@ class SurfaceEGL : public SurfaceGL ...@@ -48,7 +47,6 @@ class SurfaceEGL : public SurfaceGL
protected: protected:
const FunctionsEGL *mEGL; const FunctionsEGL *mEGL;
EGLConfig mConfig; EGLConfig mConfig;
std::vector<EGLint> mAttribList;
EGLSurface mSurface; EGLSurface mSurface;
}; };
......
...@@ -8,6 +8,9 @@ ...@@ -8,6 +8,9 @@
#include "libANGLE/renderer/gl/egl/WindowSurfaceEGL.h" #include "libANGLE/renderer/gl/egl/WindowSurfaceEGL.h"
#include "libANGLE/Surface.h"
#include "libANGLE/renderer/gl/egl/egl_utils.h"
namespace rx namespace rx
{ {
...@@ -15,9 +18,8 @@ WindowSurfaceEGL::WindowSurfaceEGL(const egl::SurfaceState &state, ...@@ -15,9 +18,8 @@ WindowSurfaceEGL::WindowSurfaceEGL(const egl::SurfaceState &state,
const FunctionsEGL *egl, const FunctionsEGL *egl,
EGLConfig config, EGLConfig config,
EGLNativeWindowType window, EGLNativeWindowType window,
const std::vector<EGLint> &attribList,
RendererGL *renderer) RendererGL *renderer)
: SurfaceEGL(state, egl, config, attribList, renderer), mWindow(window) : SurfaceEGL(state, egl, config, renderer), mWindow(window)
{ {
} }
...@@ -27,7 +29,15 @@ WindowSurfaceEGL::~WindowSurfaceEGL() ...@@ -27,7 +29,15 @@ WindowSurfaceEGL::~WindowSurfaceEGL()
egl::Error WindowSurfaceEGL::initialize(const egl::Display *display) 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) if (mSurface == EGL_NO_SURFACE)
{ {
return egl::Error(mEGL->getError(), "eglCreateWindowSurface failed"); return egl::Error(mEGL->getError(), "eglCreateWindowSurface failed");
......
...@@ -21,7 +21,6 @@ class WindowSurfaceEGL : public SurfaceEGL ...@@ -21,7 +21,6 @@ class WindowSurfaceEGL : public SurfaceEGL
const FunctionsEGL *egl, const FunctionsEGL *egl,
EGLConfig config, EGLConfig config,
EGLNativeWindowType window, EGLNativeWindowType window,
const std::vector<EGLint> &attribList,
RendererGL *renderer); RendererGL *renderer);
~WindowSurfaceEGL() override; ~WindowSurfaceEGL() override;
......
...@@ -175,7 +175,7 @@ SurfaceImpl *DisplayAndroid::createWindowSurface(const egl::SurfaceState &state, ...@@ -175,7 +175,7 @@ SurfaceImpl *DisplayAndroid::createWindowSurface(const egl::SurfaceState &state,
success = mEGL->chooseConfig(configAttribList, &config, 1, &numConfig); success = mEGL->chooseConfig(configAttribList, &config, 1, &numConfig);
ASSERT(success && numConfig == 1); 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, SurfaceImpl *DisplayAndroid::createPbufferSurface(const egl::SurfaceState &state,
...@@ -189,7 +189,7 @@ 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); success = mEGL->chooseConfig(configAttribList, &config, 1, &numConfig);
ASSERT(success && numConfig == 1); 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, 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 @@ ...@@ -653,6 +653,8 @@
[ [
'libANGLE/renderer/gl/egl/DisplayEGL.cpp', 'libANGLE/renderer/gl/egl/DisplayEGL.cpp',
'libANGLE/renderer/gl/egl/DisplayEGL.h', '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.cpp',
'libANGLE/renderer/gl/egl/FunctionsEGL.h', 'libANGLE/renderer/gl/egl/FunctionsEGL.h',
'libANGLE/renderer/gl/egl/functionsegl_typedefs.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