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