Commit e3b10e8d by Corentin Wallez

Make eglMakeCurrent validate for config compatibility

See section 2.2 of the EGL 1.5 specification. BUG=angleproject:892 Change-Id: I2a43260e53cb045b2e06b0e50915e228cec96f33 Reviewed-on: https://chromium-review.googlesource.com/272370Reviewed-by: 's avatarGeoff Lang <geofflang@chromium.org> Tested-by: 's avatarCorentin Wallez <cwallez@chromium.org>
parent 5b2545bf
......@@ -38,6 +38,7 @@ namespace gl
Context::Context(const egl::Config *config, int clientVersion, const Context *shareContext, rx::Renderer *renderer, bool notifyResets, bool robustAccess)
: mRenderer(renderer),
mConfig(config),
mData(clientVersion, mState, mCaps, mTextureCaps, mExtensions, nullptr)
{
ASSERT(robustAccess == false); // Unimplemented
......@@ -47,7 +48,6 @@ Context::Context(const egl::Config *config, int clientVersion, const Context *sh
mClientVersion = clientVersion;
mConfigID = config->configID;
mClientType = EGL_OPENGL_ES_API;
mFenceNVHandleAllocator.setBaseHandle(0);
......@@ -1320,9 +1320,9 @@ int Context::getClientVersion() const
return mClientVersion;
}
EGLint Context::getConfigID() const
const egl::Config *Context::getConfig() const
{
return mConfigID;
return mConfig;
}
EGLenum Context::getClientType() const
......
......@@ -179,7 +179,7 @@ class Context final : angle::NonCopyable
virtual int getClientVersion() const;
EGLint getConfigID() const;
const egl::Config *getConfig() const;
EGLenum getClientType() const;
EGLenum getRenderBuffer() const;
......@@ -227,7 +227,7 @@ class Context final : angle::NonCopyable
int mClientVersion;
EGLint mConfigID;
const egl::Config *mConfig;
EGLenum mClientType;
TextureMap mZeroTextures;
......
......@@ -498,4 +498,37 @@ Error ValidateCreatePbufferFromClientBuffer(Display *display, EGLenum buftype, E
return Error(EGL_SUCCESS);
}
Error ValidateCompatibleConfigs(const Config *config1, const Config *config2, EGLint surfaceType)
{
// Config compatibility is defined in section 2.2 of the EGL 1.5 spec
bool colorBufferCompat = config1->colorBufferType == config2->colorBufferType;
if (!colorBufferCompat)
{
return Error(EGL_BAD_MATCH, "Color buffer types are not compatible.");
}
bool colorCompat = config1->redSize == config2->redSize && config1->greenSize == config2->greenSize &&
config1->blueSize == config2->blueSize && config1->alphaSize == config2->alphaSize &&
config1->luminanceSize == config2->luminanceSize;
if (!colorCompat)
{
return Error(EGL_BAD_MATCH, "Color buffer sizes are not compatible.");
}
bool dsCompat = config1->depthSize == config2->depthSize && config1->stencilSize == config2->stencilSize;
if (!dsCompat)
{
return Error(EGL_BAD_MATCH, "Depth-stencil buffer types are not compatible.");
}
bool surfaceTypeCompat = (config1->surfaceType & config2->surfaceType & surfaceType) != 0;
if (!surfaceTypeCompat)
{
return Error(EGL_BAD_MATCH, "Surface types are not compatible.");
}
return Error(EGL_SUCCESS);
}
}
......@@ -43,6 +43,8 @@ Error ValidateCreatePbufferSurface(Display *display, Config *config, const Attri
Error ValidateCreatePbufferFromClientBuffer(Display *display, EGLenum buftype, EGLClientBuffer buffer,
Config *config, const AttributeMap& attributes);
// Other validation
Error ValidateCompatibleConfigs(const Config *config1, const Config *config2, EGLint surfaceType);
}
......
......@@ -519,8 +519,7 @@ EGLBoolean EGLAPIENTRY MakeCurrent(EGLDisplay dpy, EGLSurface draw, EGLSurface r
}
// EGL 1.5 spec: dpy can be uninitialized if all other parameters are null
if (dpy != EGL_NO_DISPLAY && !display->isInitialized() &&
(ctx != EGL_NO_CONTEXT || draw != EGL_NO_SURFACE || read != EGL_NO_SURFACE))
if (!display->isInitialized() && (ctx != EGL_NO_CONTEXT || draw != EGL_NO_SURFACE || read != EGL_NO_SURFACE))
{
SetGlobalError(Error(EGL_NOT_INITIALIZED, "'dpy' not initialized"));
return EGL_FALSE;
......@@ -536,7 +535,7 @@ EGLBoolean EGLAPIENTRY MakeCurrent(EGLDisplay dpy, EGLSurface draw, EGLSurface r
}
}
if (dpy != EGL_NO_DISPLAY && display->isInitialized())
if (display->isInitialized())
{
if (display->testDeviceLost())
{
......@@ -573,9 +572,29 @@ EGLBoolean EGLAPIENTRY MakeCurrent(EGLDisplay dpy, EGLSurface draw, EGLSurface r
}
}
if (readSurface)
{
Error readCompatError = ValidateCompatibleConfigs(readSurface->getConfig(), context->getConfig(), readSurface->getType());
if (readCompatError.isError())
{
SetGlobalError(readCompatError);
return EGL_FALSE;
}
}
if (draw != read)
{
UNIMPLEMENTED(); // FIXME
if (drawSurface)
{
Error drawCompatError = ValidateCompatibleConfigs(drawSurface->getConfig(), context->getConfig(), drawSurface->getType());
if (drawCompatError.isError())
{
SetGlobalError(drawCompatError);
return EGL_FALSE;
}
}
}
gl::Context *previousContext = GetGlobalContext();
......@@ -647,7 +666,7 @@ EGLBoolean EGLAPIENTRY QueryContext(EGLDisplay dpy, EGLContext ctx, EGLint attri
switch (attribute)
{
case EGL_CONFIG_ID:
*value = context->getConfigID();
*value = context->getConfig()->configID;
break;
case EGL_CONTEXT_CLIENT_TYPE:
*value = context->getClientType();
......
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