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();