Move the EGL shared image creation implementation to the context.
BUG=18110152
Change-Id: I21aece83756f033f579f11c0fb2e9e3d21f93703
Reviewed-on: https://swiftshader-review.googlesource.com/1262
Reviewed-by: Nicolas Capens <nicolascapens@google.com>
Tested-by: Nicolas Capens <nicolascapens@google.com>
diff --git a/src/GLES2/libEGL/Context.hpp b/src/GLES2/libEGL/Context.hpp
index d8ce02d..c7ac343 100644
--- a/src/GLES2/libEGL/Context.hpp
+++ b/src/GLES2/libEGL/Context.hpp
@@ -1,6 +1,16 @@
#ifndef egl_Context_hpp
#define egl_Context_hpp
+#define EGLAPI
+#include <EGL/egl.h>
+#define GL_API
+#include <GLES/gl.h>
+
+namespace gl
+{
+class Image;
+}
+
namespace egl
{
class Surface;
@@ -10,6 +20,8 @@
public:
virtual void destroy() = 0;
virtual void bindTexImage(Surface *surface) = 0;
+ virtual EGLenum validateSharedImage(EGLenum target, GLuint name, GLuint textureLevel) = 0;
+ virtual gl::Image *createSharedImage(EGLenum target, GLuint name, GLuint textureLevel) = 0;
};
}
diff --git a/src/GLES2/libEGL/Display.cpp b/src/GLES2/libEGL/Display.cpp
index b80ef75..5d6d7c7 100644
--- a/src/GLES2/libEGL/Display.cpp
+++ b/src/GLES2/libEGL/Display.cpp
@@ -16,7 +16,6 @@
#include "Display.h"
#include "main.h"
-#include "libGLESv2/mathutil.h"
#include "libGLESv2/Device.hpp"
#include "libEGL/Surface.h"
#include "libEGL/Context.hpp"
diff --git a/src/GLES2/libEGL/Surface.cpp b/src/GLES2/libEGL/Surface.cpp
index 06c84a2..11287ef 100644
--- a/src/GLES2/libEGL/Surface.cpp
+++ b/src/GLES2/libEGL/Surface.cpp
@@ -312,7 +312,7 @@
if(static_cast<egl::Surface*>(getCurrentDrawSurface()) == this)
{
- gl::makeCurrent(static_cast<gl::Context*>(getCurrentContext()), static_cast<egl::Display*>(getCurrentDisplay()), this);
+ gl::makeCurrent(static_cast<egl::Context*>(getCurrentContext()), static_cast<egl::Display*>(getCurrentDisplay()), this);
}
return true;
diff --git a/src/GLES2/libEGL/libEGL.cpp b/src/GLES2/libEGL/libEGL.cpp
index f5a6105..1130a50 100644
--- a/src/GLES2/libEGL/libEGL.cpp
+++ b/src/GLES2/libEGL/libEGL.cpp
@@ -15,8 +15,8 @@
#include "Display.h"
#include "Surface.h"
#include "Texture2D.hpp"
-#include "libGLESv2/Context.h"
-#include "libGLESv2/Texture.h"
+#include "Context.hpp"
+#include "libGLESv2/Image.hpp"
#include "common/debug.h"
#include "Common/Version.h"
@@ -845,7 +845,7 @@
try
{
egl::Display *display = static_cast<egl::Display*>(dpy);
- gl::Context *context = static_cast<gl::Context*>(ctx);
+ egl::Context *context = static_cast<egl::Context*>(ctx);
if(ctx != EGL_NO_CONTEXT && !validateContext(display, context))
{
@@ -953,7 +953,7 @@
try
{
egl::Display *display = static_cast<egl::Display*>(dpy);
- gl::Context *context = static_cast<gl::Context*>(ctx);
+ egl::Context *context = static_cast<egl::Context*>(ctx);
if(!validateContext(display, context))
{
@@ -1070,7 +1070,7 @@
try
{
egl::Display *display = static_cast<egl::Display*>(dpy);
- gl::Context *context = static_cast<gl::Context*>(ctx);
+ egl::Context *context = static_cast<egl::Context*>(ctx);
if(!validateDisplay(display))
{
@@ -1082,27 +1082,6 @@
return error(EGL_BAD_CONTEXT, EGL_NO_IMAGE_KHR);
}
- GLenum textureTarget = GL_NONE;
-
- switch(target)
- {
- case EGL_GL_TEXTURE_2D_KHR:
- textureTarget = GL_TEXTURE_2D;
- break;
- case EGL_GL_TEXTURE_CUBE_MAP_POSITIVE_X_KHR:
- case EGL_GL_TEXTURE_CUBE_MAP_NEGATIVE_X_KHR:
- case EGL_GL_TEXTURE_CUBE_MAP_POSITIVE_Y_KHR:
- case EGL_GL_TEXTURE_CUBE_MAP_NEGATIVE_Y_KHR:
- case EGL_GL_TEXTURE_CUBE_MAP_POSITIVE_Z_KHR:
- case EGL_GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_KHR:
- textureTarget = GL_TEXTURE_CUBE_MAP;
- break;
- case EGL_GL_RENDERBUFFER_KHR:
- break;
- default:
- return error(EGL_BAD_PARAMETER, EGL_NO_IMAGE_KHR);
- }
-
EGLenum imagePreserved = EGL_FALSE;
GLuint textureLevel = 0;
if(attrib_list)
@@ -1124,11 +1103,6 @@
}
}
- if(textureLevel >= gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS)
- {
- return error(EGL_BAD_MATCH, EGL_NO_IMAGE_KHR);
- }
-
GLuint name = reinterpret_cast<intptr_t>(buffer);
if(name == 0)
@@ -1136,51 +1110,14 @@
return error(EGL_BAD_PARAMETER, EGL_NO_IMAGE_KHR);
}
- gl::Image *image = 0;
+ EGLenum validationResult = context->validateSharedImage(target, name, textureLevel);
- if(textureTarget != GL_NONE)
- {
- gl::Texture *texture = context->getTexture(name);
+ if(validationResult != EGL_SUCCESS)
+ {
+ return error(validationResult, EGL_NO_IMAGE_KHR);
+ }
- if(!texture || texture->getTarget() != textureTarget)
- {
- return error(EGL_BAD_PARAMETER, EGL_NO_IMAGE_KHR);
- }
-
- if(texture->isShared(textureTarget, textureLevel)) // Bound to an EGLSurface or already an EGLImage sibling
- {
- return error(EGL_BAD_ACCESS, EGL_NO_IMAGE_KHR);
- }
-
- if(textureLevel != 0 && !texture->isSamplerComplete())
- {
- return error(EGL_BAD_PARAMETER, EGL_NO_IMAGE_KHR);
- }
-
- if(textureLevel == 0 && !(texture->isSamplerComplete() && texture->getLevelCount() == 1))
- {
- return error(EGL_BAD_PARAMETER, EGL_NO_IMAGE_KHR);
- }
-
- image = texture->createSharedImage(textureTarget, textureLevel);
- }
- else if(target == EGL_GL_RENDERBUFFER_KHR)
- {
- gl::Renderbuffer *renderbuffer = context->getRenderbuffer(name);
-
- if(!renderbuffer)
- {
- return error(EGL_BAD_PARAMETER, EGL_NO_IMAGE_KHR);
- }
-
- if(renderbuffer->isShared()) // Already an EGLImage sibling
- {
- return error(EGL_BAD_ACCESS, EGL_NO_IMAGE_KHR);
- }
-
- image = renderbuffer->createSharedImage();
- }
- else UNREACHABLE();
+ gl::Image *image = context->createSharedImage(target, name, textureLevel);
if(!image)
{
diff --git a/src/GLES2/libEGL/main.cpp b/src/GLES2/libEGL/main.cpp
index dfbfee1..96a2d9c 100644
--- a/src/GLES2/libEGL/main.cpp
+++ b/src/GLES2/libEGL/main.cpp
@@ -91,7 +91,7 @@
libGLESv2 = loadLibrary(libGLESv2_lib);
gl::createDevice = (gl::Device*(*)())getProcAddress(libGLESv2, "createDevice");
gl::createContext = (egl::Context *(*)(const egl::Config*, const egl::Context*))getProcAddress(libGLESv2, "glCreateContext");
- gl::makeCurrent = (void (*)(gl::Context*, egl::Display*, egl::Surface*))getProcAddress(libGLESv2, "glMakeCurrent");
+ gl::makeCurrent = (void (*)(egl::Context*, egl::Display*, egl::Surface*))getProcAddress(libGLESv2, "glMakeCurrent");
gl::getProcAddress = (__eglMustCastToProperFunctionPointerType (*)(const char*))getProcAddress(libGLESv2, "glGetProcAddress");
gl::createBackBuffer = (gl::Image *(*)(int, int, const egl::Config*))getProcAddress(libGLESv2, "createBackBuffer");
gl::createFrameBuffer = (sw::FrameBuffer *(*)(EGLNativeDisplayType, EGLNativeWindowType, int, int))getProcAddress(libGLESv2, "createFrameBuffer");
@@ -263,8 +263,8 @@
Device *(*createDevice)() = 0;
egl::Context *(*createContext)(const egl::Config *config, const egl::Context *shareContext) = 0;
void (*bindTexImage)(egl::Surface *surface) = 0;
- void (*makeCurrent)(Context *context, egl::Display *display, egl::Surface *surface) = 0;
- Context *(*getCurrentContext)() = 0;
+ void (*makeCurrent)(egl::Context *context, egl::Display *display, egl::Surface *surface) = 0;
+ egl::Context *(*getCurrentContext)() = 0;
__eglMustCastToProperFunctionPointerType (*getProcAddress)(const char *procname) = 0;
Image *(*createBackBuffer)(int width, int height, const egl::Config *config) = 0;
sw::FrameBuffer *(*createFrameBuffer)(EGLNativeDisplayType display, EGLNativeWindowType window, int width, int height) = 0;
diff --git a/src/GLES2/libEGL/main.h b/src/GLES2/libEGL/main.h
index 01a6873..cf6973c 100644
--- a/src/GLES2/libEGL/main.h
+++ b/src/GLES2/libEGL/main.h
@@ -84,12 +84,11 @@
namespace gl
{
class Device;
- class Context;
class Image;
extern Device *(*createDevice)();
extern egl::Context *(*createContext)(const egl::Config *config, const egl::Context *shareContext);
- extern void (*makeCurrent)(Context *context, egl::Display *display, egl::Surface *surface);
+ extern void (*makeCurrent)(egl::Context *context, egl::Display *display, egl::Surface *surface);
extern __eglMustCastToProperFunctionPointerType (*getProcAddress)(const char *procname);
extern Image *(*createBackBuffer)(int width, int height, const egl::Config *config);
extern sw::FrameBuffer *(*createFrameBuffer)(EGLNativeDisplayType display, EGLNativeWindowType window, int width, int height);
diff --git a/src/GLES2/libGLES_CM/Context.cpp b/src/GLES2/libGLES_CM/Context.cpp
index d07f444..541b733 100644
--- a/src/GLES2/libGLES_CM/Context.cpp
+++ b/src/GLES2/libGLES_CM/Context.cpp
@@ -29,6 +29,8 @@
#include "libEGL/Surface.h"
#include "Common/Half.hpp"
+#include <EGL/eglext.h>
+
#undef near
#undef far
@@ -2226,6 +2228,85 @@
}
}
+EGLenum Context::validateSharedImage(EGLenum target, GLuint name, GLuint textureLevel)
+{
+ switch(target)
+ {
+ case EGL_GL_TEXTURE_2D_KHR:
+ break;
+ case EGL_GL_RENDERBUFFER_KHR:
+ break;
+ default:
+ return EGL_BAD_PARAMETER;
+ }
+
+ if(textureLevel >= IMPLEMENTATION_MAX_TEXTURE_LEVELS)
+ {
+ return EGL_BAD_MATCH;
+ }
+
+ if(target == EGL_GL_TEXTURE_2D_KHR)
+ {
+ Texture *texture = getTexture(name);
+
+ if(!texture || texture->getTarget() != target)
+ {
+ return EGL_BAD_PARAMETER;
+ }
+
+ if(texture->isShared(GL_TEXTURE_2D, textureLevel)) // Bound to an EGLSurface or already an EGLImage sibling
+ {
+ return EGL_BAD_ACCESS;
+ }
+
+ if(textureLevel != 0 && !texture->isSamplerComplete())
+ {
+ return EGL_BAD_PARAMETER;
+ }
+
+ if(textureLevel == 0 && !(texture->isSamplerComplete() && texture->getLevelCount() == 1))
+ {
+ return EGL_BAD_PARAMETER;
+ }
+ }
+ else if(target == EGL_GL_RENDERBUFFER_KHR)
+ {
+ Renderbuffer *renderbuffer = getRenderbuffer(name);
+
+ if(!renderbuffer)
+ {
+ return EGL_BAD_PARAMETER;
+ }
+
+ if(renderbuffer->isShared()) // Already an EGLImage sibling
+ {
+ return EGL_BAD_ACCESS;
+ }
+ }
+ else UNREACHABLE();
+
+ return EGL_SUCCESS;
+}
+
+Image *Context::createSharedImage(EGLenum target, GLuint name, GLuint textureLevel)
+{
+ if(target == EGL_GL_TEXTURE_2D_KHR)
+ {
+ gl::Texture *texture = getTexture(name);
+
+ return texture->createSharedImage(GL_TEXTURE_2D, textureLevel);
+ }
+ else if(target == EGL_GL_RENDERBUFFER_KHR)
+ {
+ gl::Renderbuffer *renderbuffer = getRenderbuffer(name);
+
+ return renderbuffer->createSharedImage();
+ }
+ else UNREACHABLE();
+
+ return 0;
+}
+
}
// Exported functions for use by EGL
diff --git a/src/GLES2/libGLES_CM/Context.h b/src/GLES2/libGLES_CM/Context.h
index ee4d38f..cf6f939 100644
--- a/src/GLES2/libGLES_CM/Context.h
+++ b/src/GLES2/libGLES_CM/Context.h
@@ -368,6 +368,8 @@
static int getSupportedMultiSampleDepth(sw::Format format, int requested);
virtual void bindTexImage(egl::Surface *surface);
+ virtual EGLenum validateSharedImage(EGLenum target, GLuint name, GLuint textureLevel);
+ virtual Image *createSharedImage(EGLenum target, GLuint name, GLuint textureLevel);
private:
virtual ~Context();
diff --git a/src/GLES2/libGLESv2/Context.cpp b/src/GLES2/libGLESv2/Context.cpp
index c54e140..d4e48fb 100644
--- a/src/GLES2/libGLESv2/Context.cpp
+++ b/src/GLES2/libGLESv2/Context.cpp
@@ -32,6 +32,8 @@
#include "libEGL/Surface.h"
#include "Common/Half.hpp"
+#include <EGL/eglext.h>
+
#undef near
#undef far
@@ -3039,6 +3041,109 @@
}
}
+EGLenum Context::validateSharedImage(EGLenum target, GLuint name, GLuint textureLevel)
+{
+ GLenum textureTarget = GL_NONE;
+
+ switch(target)
+ {
+ case EGL_GL_TEXTURE_2D_KHR:
+ textureTarget = GL_TEXTURE_2D;
+ break;
+ case EGL_GL_TEXTURE_CUBE_MAP_POSITIVE_X_KHR:
+ case EGL_GL_TEXTURE_CUBE_MAP_NEGATIVE_X_KHR:
+ case EGL_GL_TEXTURE_CUBE_MAP_POSITIVE_Y_KHR:
+ case EGL_GL_TEXTURE_CUBE_MAP_NEGATIVE_Y_KHR:
+ case EGL_GL_TEXTURE_CUBE_MAP_POSITIVE_Z_KHR:
+ case EGL_GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_KHR:
+ textureTarget = GL_TEXTURE_CUBE_MAP;
+ break;
+ case EGL_GL_RENDERBUFFER_KHR:
+ break;
+ default:
+ return EGL_BAD_PARAMETER;
+ }
+
+ if(textureLevel >= gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS)
+ {
+ return EGL_BAD_MATCH;
+ }
+
+ if(textureTarget != GL_NONE)
+ {
+ gl::Texture *texture = getTexture(name);
+
+ if(!texture || texture->getTarget() != textureTarget)
+ {
+ return EGL_BAD_PARAMETER;
+ }
+
+ if(texture->isShared(textureTarget, textureLevel)) // Bound to an EGLSurface or already an EGLImage sibling
+ {
+ return EGL_BAD_ACCESS;
+ }
+
+ if(textureLevel != 0 && !texture->isSamplerComplete())
+ {
+ return EGL_BAD_PARAMETER;
+ }
+
+ if(textureLevel == 0 && !(texture->isSamplerComplete() && texture->getLevelCount() == 1))
+ {
+ return EGL_BAD_PARAMETER;
+ }
+ }
+ else if(target == EGL_GL_RENDERBUFFER_KHR)
+ {
+ gl::Renderbuffer *renderbuffer = getRenderbuffer(name);
+
+ if(!renderbuffer)
+ {
+ return EGL_BAD_PARAMETER;
+ }
+
+ if(renderbuffer->isShared()) // Already an EGLImage sibling
+ {
+ return EGL_BAD_ACCESS;
+ }
+ }
+ else UNREACHABLE();
+
+ return EGL_SUCCESS;
+}
+
+Image *Context::createSharedImage(EGLenum target, GLuint name, GLuint textureLevel)
+{
+ GLenum textureTarget = GL_NONE;
+
+ switch(target)
+ {
+ case EGL_GL_TEXTURE_2D_KHR: textureTarget = GL_TEXTURE_2D; break;
+ case EGL_GL_TEXTURE_CUBE_MAP_POSITIVE_X_KHR: textureTarget = GL_TEXTURE_CUBE_MAP_POSITIVE_X; break;
+ case EGL_GL_TEXTURE_CUBE_MAP_NEGATIVE_X_KHR: textureTarget = GL_TEXTURE_CUBE_MAP_NEGATIVE_X; break;
+ case EGL_GL_TEXTURE_CUBE_MAP_POSITIVE_Y_KHR: textureTarget = GL_TEXTURE_CUBE_MAP_POSITIVE_Y; break;
+ case EGL_GL_TEXTURE_CUBE_MAP_NEGATIVE_Y_KHR: textureTarget = GL_TEXTURE_CUBE_MAP_NEGATIVE_Y; break;
+ case EGL_GL_TEXTURE_CUBE_MAP_POSITIVE_Z_KHR: textureTarget = GL_TEXTURE_CUBE_MAP_POSITIVE_Z; break;
+ case EGL_GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_KHR: textureTarget = GL_TEXTURE_CUBE_MAP_NEGATIVE_Z; break;
+ }
+
+ if(textureTarget != GL_NONE)
+ {
+ gl::Texture *texture = getTexture(name);
+
+ return texture->createSharedImage(textureTarget, textureLevel);
+ }
+ else if(target == EGL_GL_RENDERBUFFER_KHR)
+ {
+ gl::Renderbuffer *renderbuffer = getRenderbuffer(name);
+
+ return renderbuffer->createSharedImage();
+ }
+ else UNREACHABLE();
+
+ return 0;
+}
+
}
// Exported functions for use by EGL
diff --git a/src/GLES2/libGLESv2/Context.h b/src/GLES2/libGLESv2/Context.h
index aefd7bd..7e83f0b 100644
--- a/src/GLES2/libGLESv2/Context.h
+++ b/src/GLES2/libGLESv2/Context.h
@@ -420,6 +420,8 @@
GLbitfield mask);
virtual void bindTexImage(egl::Surface *surface);
+ virtual EGLenum validateSharedImage(EGLenum target, GLuint name, GLuint textureLevel);
+ virtual gl::Image *createSharedImage(EGLenum target, GLuint name, GLuint textureLevel);
private:
virtual ~Context();