Commit f81b6a15 by Geoff Lang

Move eglCreatePbuffer* validation into validationEGL.

BUG=angle:658 Change-Id: I25d1be1ef86f82892186b08c9a8ff0133d520ac6 Reviewed-on: https://chromium-review.googlesource.com/242037Reviewed-by: 's avatarBrandon Jones <bajones@chromium.org> Reviewed-by: 's avatarKenneth Russell <kbr@chromium.org> Tested-by: 's avatarGeoff Lang <geofflang@chromium.org>
parent 0eef0826
...@@ -265,99 +265,13 @@ Error Display::createWindowSurface(const Config *configuration, EGLNativeWindowT ...@@ -265,99 +265,13 @@ Error Display::createWindowSurface(const Config *configuration, EGLNativeWindowT
return Error(EGL_SUCCESS); return Error(EGL_SUCCESS);
} }
Error Display::createOffscreenSurface(const Config *configuration, EGLClientBuffer shareHandle, Error Display::createOffscreenSurface(const Config *configuration, EGLClientBuffer shareHandle, const AttributeMap &attribs,
const EGLint *attribList, EGLSurface *outSurface) Surface **outSurface)
{ {
EGLint width = 0, height = 0; EGLint width = attribs.get(EGL_WIDTH, 0);
EGLenum textureFormat = EGL_NO_TEXTURE; EGLint height = attribs.get(EGL_HEIGHT, 0);
EGLenum textureTarget = EGL_NO_TEXTURE; EGLenum textureFormat = attribs.get(EGL_TEXTURE_FORMAT, EGL_NO_TEXTURE);
EGLenum textureTarget = attribs.get(EGL_TEXTURE_TARGET, EGL_NO_TEXTURE);
if (attribList)
{
while (*attribList != EGL_NONE)
{
switch (attribList[0])
{
case EGL_WIDTH:
width = attribList[1];
break;
case EGL_HEIGHT:
height = attribList[1];
break;
case EGL_LARGEST_PBUFFER:
if (attribList[1] != EGL_FALSE)
UNIMPLEMENTED(); // FIXME
break;
case EGL_TEXTURE_FORMAT:
switch (attribList[1])
{
case EGL_NO_TEXTURE:
case EGL_TEXTURE_RGB:
case EGL_TEXTURE_RGBA:
textureFormat = attribList[1];
break;
default:
return Error(EGL_BAD_ATTRIBUTE);
}
break;
case EGL_TEXTURE_TARGET:
switch (attribList[1])
{
case EGL_NO_TEXTURE:
case EGL_TEXTURE_2D:
textureTarget = attribList[1];
break;
default:
return Error(EGL_BAD_ATTRIBUTE);
}
break;
case EGL_MIPMAP_TEXTURE:
if (attribList[1] != EGL_FALSE)
return Error(EGL_BAD_ATTRIBUTE);
break;
case EGL_VG_COLORSPACE:
return Error(EGL_BAD_MATCH);
case EGL_VG_ALPHA_FORMAT:
return Error(EGL_BAD_MATCH);
default:
return Error(EGL_BAD_ATTRIBUTE);
}
attribList += 2;
}
}
if (width < 0 || height < 0)
{
return Error(EGL_BAD_PARAMETER);
}
if (width == 0 || height == 0)
{
return Error(EGL_BAD_ATTRIBUTE);
}
if (textureFormat != EGL_NO_TEXTURE && !mCaps.textureNPOT && (!gl::isPow2(width) || !gl::isPow2(height)))
{
return Error(EGL_BAD_MATCH);
}
if ((textureFormat != EGL_NO_TEXTURE && textureTarget == EGL_NO_TEXTURE) ||
(textureFormat == EGL_NO_TEXTURE && textureTarget != EGL_NO_TEXTURE))
{
return Error(EGL_BAD_MATCH);
}
if (!(configuration->surfaceType & EGL_PBUFFER_BIT))
{
return Error(EGL_BAD_MATCH);
}
if ((textureFormat == EGL_TEXTURE_RGB && configuration->bindToTextureRGB != EGL_TRUE) ||
(textureFormat == EGL_TEXTURE_RGBA && configuration->bindToTextureRGBA != EGL_TRUE))
{
return Error(EGL_BAD_ATTRIBUTE);
}
if (mImplementation->testDeviceLost()) if (mImplementation->testDeviceLost())
{ {
......
...@@ -51,7 +51,8 @@ class Display final ...@@ -51,7 +51,8 @@ class Display final
Error createWindowSurface(const Config *configuration, EGLNativeWindowType window, const AttributeMap &attribs, Error createWindowSurface(const Config *configuration, EGLNativeWindowType window, const AttributeMap &attribs,
Surface **outSurface); Surface **outSurface);
Error createOffscreenSurface(const Config *configuration, EGLClientBuffer shareHandle, const EGLint *attribList, EGLSurface *outSurface); Error createOffscreenSurface(const Config *configuration, EGLClientBuffer shareHandle, const AttributeMap &attribs,
Surface **outSurface);
Error createContext(const Config *configuration, gl::Context *shareContext, const AttributeMap &attribs, Error createContext(const Config *configuration, gl::Context *shareContext, const AttributeMap &attribs,
gl::Context **outContext); gl::Context **outContext);
......
...@@ -286,4 +286,216 @@ Error ValidateCreateWindowSurface(Display *display, Config *config, EGLNativeWin ...@@ -286,4 +286,216 @@ Error ValidateCreateWindowSurface(Display *display, Config *config, EGLNativeWin
return Error(EGL_SUCCESS); return Error(EGL_SUCCESS);
} }
Error ValidateCreatePbufferSurface(Display *display, Config *config, const AttributeMap& attributes)
{
Error error = ValidateConfig(display, config);
if (error.isError())
{
return error;
}
for (AttributeMap::const_iterator attributeIter = attributes.begin(); attributeIter != attributes.end(); attributeIter++)
{
EGLint attribute = attributeIter->first;
EGLint value = attributeIter->second;
switch (attribute)
{
case EGL_WIDTH:
case EGL_HEIGHT:
if (value < 0)
{
return Error(EGL_BAD_PARAMETER);
}
break;
case EGL_LARGEST_PBUFFER:
break;
case EGL_TEXTURE_FORMAT:
switch (value)
{
case EGL_NO_TEXTURE:
case EGL_TEXTURE_RGB:
case EGL_TEXTURE_RGBA:
break;
default:
return Error(EGL_BAD_ATTRIBUTE);
}
break;
case EGL_TEXTURE_TARGET:
switch (value)
{
case EGL_NO_TEXTURE:
case EGL_TEXTURE_2D:
break;
default:
return Error(EGL_BAD_ATTRIBUTE);
}
break;
case EGL_MIPMAP_TEXTURE:
break;
case EGL_VG_COLORSPACE:
break;
case EGL_VG_ALPHA_FORMAT:
break;
default:
return Error(EGL_BAD_ATTRIBUTE);
}
}
if (!(config->surfaceType & EGL_PBUFFER_BIT))
{
return Error(EGL_BAD_MATCH);
}
const Caps &caps = display->getCaps();
EGLenum textureFormat = attributes.get(EGL_TEXTURE_FORMAT, EGL_NO_TEXTURE);
EGLenum textureTarget = attributes.get(EGL_TEXTURE_TARGET, EGL_NO_TEXTURE);
if ((textureFormat != EGL_NO_TEXTURE && textureTarget == EGL_NO_TEXTURE) ||
(textureFormat == EGL_NO_TEXTURE && textureTarget != EGL_NO_TEXTURE))
{
return Error(EGL_BAD_MATCH);
}
if ((textureFormat == EGL_TEXTURE_RGB && config->bindToTextureRGB != EGL_TRUE) ||
(textureFormat == EGL_TEXTURE_RGBA && config->bindToTextureRGBA != EGL_TRUE))
{
return Error(EGL_BAD_ATTRIBUTE);
}
EGLint width = attributes.get(EGL_WIDTH, 0);
EGLint height = attributes.get(EGL_HEIGHT, 0);
if (textureFormat != EGL_NO_TEXTURE && !caps.textureNPOT && (!gl::isPow2(width) || !gl::isPow2(height)))
{
return Error(EGL_BAD_MATCH);
}
return Error(EGL_SUCCESS);
}
Error ValidateCreatePbufferFromClientBuffer(Display *display, EGLenum buftype, EGLClientBuffer buffer,
Config *config, const AttributeMap& attributes)
{
Error error = ValidateConfig(display, config);
if (error.isError())
{
return error;
}
const DisplayExtensions &displayExtensions = display->getExtensions();
switch (buftype)
{
case EGL_D3D_TEXTURE_2D_SHARE_HANDLE_ANGLE:
if (!displayExtensions.d3dShareHandleClientBuffer)
{
return Error(EGL_BAD_PARAMETER);
}
if (buffer == nullptr)
{
return Error(EGL_BAD_PARAMETER);
}
break;
default:
return Error(EGL_BAD_PARAMETER);
}
for (AttributeMap::const_iterator attributeIter = attributes.begin(); attributeIter != attributes.end(); attributeIter++)
{
EGLint attribute = attributeIter->first;
EGLint value = attributeIter->second;
switch (attribute)
{
case EGL_WIDTH:
case EGL_HEIGHT:
if (!displayExtensions.d3dShareHandleClientBuffer)
{
return Error(EGL_BAD_PARAMETER);
}
if (value < 0)
{
return Error(EGL_BAD_PARAMETER);
}
break;
case EGL_TEXTURE_FORMAT:
switch (value)
{
case EGL_NO_TEXTURE:
case EGL_TEXTURE_RGB:
case EGL_TEXTURE_RGBA:
break;
default:
return Error(EGL_BAD_ATTRIBUTE);
}
break;
case EGL_TEXTURE_TARGET:
switch (value)
{
case EGL_NO_TEXTURE:
case EGL_TEXTURE_2D:
break;
default:
return Error(EGL_BAD_ATTRIBUTE);
}
break;
case EGL_MIPMAP_TEXTURE:
break;
default:
return Error(EGL_BAD_ATTRIBUTE);
}
}
if (!(config->surfaceType & EGL_PBUFFER_BIT))
{
return Error(EGL_BAD_MATCH);
}
EGLenum textureFormat = attributes.get(EGL_TEXTURE_FORMAT, EGL_NO_TEXTURE);
EGLenum textureTarget = attributes.get(EGL_TEXTURE_TARGET, EGL_NO_TEXTURE);
if ((textureFormat != EGL_NO_TEXTURE && textureTarget == EGL_NO_TEXTURE) ||
(textureFormat == EGL_NO_TEXTURE && textureTarget != EGL_NO_TEXTURE))
{
return Error(EGL_BAD_MATCH);
}
if ((textureFormat == EGL_TEXTURE_RGB && config->bindToTextureRGB != EGL_TRUE) ||
(textureFormat == EGL_TEXTURE_RGBA && config->bindToTextureRGBA != EGL_TRUE))
{
return Error(EGL_BAD_ATTRIBUTE);
}
if (buftype == EGL_D3D_TEXTURE_2D_SHARE_HANDLE_ANGLE)
{
EGLint width = attributes.get(EGL_WIDTH, 0);
EGLint height = attributes.get(EGL_HEIGHT, 0);
if (width == 0 || height == 0)
{
return Error(EGL_BAD_ATTRIBUTE);
}
const Caps &caps = display->getCaps();
if (textureFormat != EGL_NO_TEXTURE && !caps.textureNPOT && (!gl::isPow2(width) || !gl::isPow2(height)))
{
return Error(EGL_BAD_MATCH);
}
}
return Error(EGL_SUCCESS);
}
} }
...@@ -39,6 +39,11 @@ Error ValidateCreateContext(Display *display, Config *configuration, gl::Context ...@@ -39,6 +39,11 @@ Error ValidateCreateContext(Display *display, Config *configuration, gl::Context
Error ValidateCreateWindowSurface(Display *display, Config *config, EGLNativeWindowType window, Error ValidateCreateWindowSurface(Display *display, Config *config, EGLNativeWindowType window,
const AttributeMap& attributes); const AttributeMap& attributes);
Error ValidateCreatePbufferSurface(Display *display, Config *config, const AttributeMap& attributes);
Error ValidateCreatePbufferFromClientBuffer(Display *display, EGLenum buftype, EGLClientBuffer buffer,
Config *config, const AttributeMap& attributes);
} }
#endif // LIBANGLE_VALIDATIONEGL_H_ #endif // LIBANGLE_VALIDATIONEGL_H_
...@@ -272,23 +272,24 @@ EGLSurface EGLAPIENTRY CreatePbufferSurface(EGLDisplay dpy, EGLConfig config, co ...@@ -272,23 +272,24 @@ EGLSurface EGLAPIENTRY CreatePbufferSurface(EGLDisplay dpy, EGLConfig config, co
Display *display = static_cast<Display*>(dpy); Display *display = static_cast<Display*>(dpy);
Config *configuration = static_cast<Config*>(config); Config *configuration = static_cast<Config*>(config);
AttributeMap attributes(attrib_list);
Error error = ValidateConfig(display, configuration); Error error = ValidateCreatePbufferSurface(display, configuration, attributes);
if (error.isError()) if (error.isError())
{ {
SetGlobalError(error); SetGlobalError(error);
return EGL_NO_SURFACE; return EGL_NO_SURFACE;
} }
EGLSurface surface = EGL_NO_SURFACE; egl::Surface *surface = nullptr;
error = display->createOffscreenSurface(configuration, NULL, attrib_list, &surface); error = display->createOffscreenSurface(configuration, NULL, attributes, &surface);
if (error.isError()) if (error.isError())
{ {
SetGlobalError(error); SetGlobalError(error);
return EGL_NO_SURFACE; return EGL_NO_SURFACE;
} }
return surface; return static_cast<EGLSurface>(surface);
} }
EGLSurface EGLAPIENTRY CreatePixmapSurface(EGLDisplay dpy, EGLConfig config, EGLNativePixmapType pixmap, const EGLint *attrib_list) EGLSurface EGLAPIENTRY CreatePixmapSurface(EGLDisplay dpy, EGLConfig config, EGLNativePixmapType pixmap, const EGLint *attrib_list)
...@@ -904,29 +905,24 @@ EGLSurface EGLAPIENTRY CreatePbufferFromClientBuffer(EGLDisplay dpy, EGLenum buf ...@@ -904,29 +905,24 @@ EGLSurface EGLAPIENTRY CreatePbufferFromClientBuffer(EGLDisplay dpy, EGLenum buf
Display *display = static_cast<Display*>(dpy); Display *display = static_cast<Display*>(dpy);
Config *configuration = static_cast<Config*>(config); Config *configuration = static_cast<Config*>(config);
AttributeMap attributes(attrib_list);
Error error = ValidateConfig(display, configuration); Error error = ValidateCreatePbufferFromClientBuffer(display, buftype, buffer, configuration, attributes);
if (error.isError()) if (error.isError())
{ {
SetGlobalError(error); SetGlobalError(error);
return EGL_NO_SURFACE; return EGL_NO_SURFACE;
} }
if (buftype != EGL_D3D_TEXTURE_2D_SHARE_HANDLE_ANGLE || !buffer) egl::Surface *surface = nullptr;
{ error = display->createOffscreenSurface(configuration, buffer, attributes, &surface);
SetGlobalError(Error(EGL_BAD_PARAMETER));
return EGL_NO_SURFACE;
}
EGLSurface surface = EGL_NO_SURFACE;
error = display->createOffscreenSurface(configuration, buffer, attrib_list, &surface);
if (error.isError()) if (error.isError())
{ {
SetGlobalError(error); SetGlobalError(error);
return EGL_NO_SURFACE; return EGL_NO_SURFACE;
} }
return surface; return static_cast<EGLSurface>(surface);
} }
EGLBoolean EGLAPIENTRY ReleaseThread(void) EGLBoolean EGLAPIENTRY ReleaseThread(void)
......
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