Store EGL images in a namespace. This allows validating the EGL image handles. It also ensures that on 64-bit platforms the handles fit in 32-bit so they can be exchanged through 32-bit applications (e.g. on a 32-bit virtual machine). Change-Id: Ie02b00edd2cf7fa02b38316ee7d21c22eae720b5 Reviewed-on: https://swiftshader-review.googlesource.com/5500 Tested-by: Nicolas Capens <capn@google.com> Reviewed-by: Alexis Hétu <sugoi@google.com> Reviewed-by: Nicolas Capens <capn@google.com>
diff --git a/src/OpenGL/libEGL/Display.cpp b/src/OpenGL/libEGL/Display.cpp index 0e8465e..f2e8555 100644 --- a/src/OpenGL/libEGL/Display.cpp +++ b/src/OpenGL/libEGL/Display.cpp
@@ -21,6 +21,7 @@ #include "main.h" #include "libEGL/Surface.h" #include "libEGL/Context.hpp" +#include "common/Image.hpp" #include "common/debug.h" #include "Common/MutexLock.hpp" @@ -196,6 +197,11 @@ { destroyContext(*mContextSet.begin()); } + + while(!mSharedImageNameSpace.empty()) + { + destroySharedImage((EGLImageKHR)mSharedImageNameSpace.firstName()); + } } bool Display::getConfigs(EGLConfig *configs, const EGLint *attribList, EGLint configSize, EGLint *numConfig) @@ -581,6 +587,33 @@ return nativeDisplay; } +EGLImageKHR Display::createSharedImage(Image *image) +{ + return (EGLImageKHR)mSharedImageNameSpace.allocate(image); +} + +bool Display::destroySharedImage(EGLImageKHR image) +{ + GLuint name = (GLuint)reinterpret_cast<intptr_t>(image); + Image *eglImage = mSharedImageNameSpace.find(name); + + if(!eglImage) + { + return false; + } + + eglImage->destroyShared(); + mSharedImageNameSpace.remove(name); + + return true; +} + +Image *Display::getSharedImage(EGLImageKHR image) +{ + GLuint name = (GLuint)reinterpret_cast<intptr_t>(image); + return mSharedImageNameSpace.find(name); +} + sw::Format Display::getDisplayFormat() const { #if defined(_WIN32)
diff --git a/src/OpenGL/libEGL/Display.h b/src/OpenGL/libEGL/Display.h index 14d0fe3..456c1f2 100644 --- a/src/OpenGL/libEGL/Display.h +++ b/src/OpenGL/libEGL/Display.h
@@ -21,6 +21,7 @@ #include "Config.h" #include "Sync.hpp" +#include "common/NameSpace.hpp" #include <set> @@ -28,6 +29,7 @@ { class Surface; class Context; + class Image; const EGLDisplay PRIMARY_DISPLAY = (EGLDisplay)1; const EGLDisplay HEADLESS_DISPLAY = (EGLDisplay)0xFACE1E55; @@ -64,7 +66,10 @@ EGLint getMaxSwapInterval() const; void *getNativeDisplay() const; - const char *getExtensionString() const; + + EGLImageKHR createSharedImage(Image *image); + bool destroySharedImage(EGLImageKHR); + virtual Image *getSharedImage(EGLImageKHR name); private: explicit Display(void *nativeDisplay); @@ -87,6 +92,8 @@ typedef std::set<FenceSync*> SyncSet; SyncSet mSyncSet; + + gl::NameSpace<Image> mSharedImageNameSpace; }; }
diff --git a/src/OpenGL/libEGL/libEGL.cbp b/src/OpenGL/libEGL/libEGL.cbp index c3c209c..df54852 100644 --- a/src/OpenGL/libEGL/libEGL.cbp +++ b/src/OpenGL/libEGL/libEGL.cbp
@@ -117,6 +117,7 @@ <Unit filename="../../Common/SharedLibrary.hpp" /> <Unit filename="../../Main/libX11.cpp" /> <Unit filename="../../Main/libX11.hpp" /> + <Unit filename="../common/NameSpace.hpp" /> <Unit filename="../common/Object.cpp" /> <Unit filename="../common/Object.hpp" /> <Unit filename="../common/debug.cpp" />
diff --git a/src/OpenGL/libEGL/libEGL.cpp b/src/OpenGL/libEGL/libEGL.cpp index 610d1c3..4d8a169 100644 --- a/src/OpenGL/libEGL/libEGL.cpp +++ b/src/OpenGL/libEGL/libEGL.cpp
@@ -982,7 +982,10 @@ return error(EGL_BAD_ATTRIBUTE, EGL_NO_IMAGE_KHR); } - return success(new AndroidNativeImage(nativeBuffer)); + Image *image = new AndroidNativeImage(nativeBuffer); + EGLImageKHR eglImage = display->createSharedImage(image); + + return success(eglImage); } #endif @@ -1000,7 +1003,7 @@ return error(validationResult, EGL_NO_IMAGE_KHR); } - egl::Image *image = context->createSharedImage(target, name, textureLevel); + Image *image = context->createSharedImage(target, name, textureLevel); if(!image) { @@ -1012,7 +1015,9 @@ return error(EGL_BAD_PARAMETER, EGL_NO_IMAGE_KHR); } - return success((EGLImageKHR)image); + EGLImageKHR eglImage = display->createSharedImage(image); + + return success(eglImage); } EGLBoolean DestroyImageKHR(EGLDisplay dpy, EGLImageKHR image) @@ -1026,14 +1031,11 @@ return error(EGL_BAD_DISPLAY, EGL_FALSE); } - if(!image) + if(!display->destroySharedImage(image)) { return error(EGL_BAD_PARAMETER, EGL_FALSE); } - egl::Image *glImage = static_cast<egl::Image*>(image); - glImage->destroyShared(); - return success(EGL_TRUE); }
diff --git a/src/OpenGL/libEGL/libEGL.vcxproj b/src/OpenGL/libEGL/libEGL.vcxproj index 9b1b7bb..e2375fd 100644 --- a/src/OpenGL/libEGL/libEGL.vcxproj +++ b/src/OpenGL/libEGL/libEGL.vcxproj
@@ -308,6 +308,7 @@ <ItemGroup> <ClInclude Include="..\common\debug.h" /> <ClInclude Include="..\common\Image.hpp" /> + <ClInclude Include="..\common\NameSpace.hpp" /> <ClInclude Include="..\common\Object.hpp" /> <ClInclude Include="..\include\EGL\egl.h" /> <ClInclude Include="..\include\EGL\eglext.h" />
diff --git a/src/OpenGL/libEGL/libEGL.vcxproj.filters b/src/OpenGL/libEGL/libEGL.vcxproj.filters index 4400f20..3848f41 100644 --- a/src/OpenGL/libEGL/libEGL.vcxproj.filters +++ b/src/OpenGL/libEGL/libEGL.vcxproj.filters
@@ -79,6 +79,9 @@ <ClInclude Include="Sync.hpp"> <Filter>Header Files</Filter> </ClInclude> + <ClInclude Include="..\common\NameSpace.hpp"> + <Filter>Header Files</Filter> + </ClInclude> </ItemGroup> <ItemGroup> <ResourceCompile Include="libEGL.rc" />
diff --git a/src/OpenGL/libGLES_CM/Context.cpp b/src/OpenGL/libGLES_CM/Context.cpp index ba34dab..0c9fed1 100644 --- a/src/OpenGL/libGLES_CM/Context.cpp +++ b/src/OpenGL/libGLES_CM/Context.cpp
@@ -3158,7 +3158,12 @@ } else UNREACHABLE(target); - return 0; + return nullptr; +} + +egl::Image *Context::getSharedImage(GLeglImageOES image) +{ + return display->getSharedImage(image); } Device *Context::getDevice()
diff --git a/src/OpenGL/libGLES_CM/Context.h b/src/OpenGL/libGLES_CM/Context.h index 2dee4fa..1bef6b6 100644 --- a/src/OpenGL/libGLES_CM/Context.h +++ b/src/OpenGL/libGLES_CM/Context.h
@@ -509,6 +509,7 @@ virtual void bindTexImage(egl::Surface *surface); virtual EGLenum validateSharedImage(EGLenum target, GLuint name, GLuint textureLevel); virtual egl::Image *createSharedImage(EGLenum target, GLuint name, GLuint textureLevel); + egl::Image *getSharedImage(GLeglImageOES image); Device *getDevice();
diff --git a/src/OpenGL/libGLES_CM/Texture.cpp b/src/OpenGL/libGLES_CM/Texture.cpp index b8817a0..4731635 100644 --- a/src/OpenGL/libGLES_CM/Texture.cpp +++ b/src/OpenGL/libGLES_CM/Texture.cpp
@@ -614,7 +614,7 @@ renderTarget->release(); } -void Texture2D::setImage(egl::Image *sharedImage) +void Texture2D::setSharedImage(egl::Image *sharedImage) { sharedImage->addRef();
diff --git a/src/OpenGL/libGLES_CM/Texture.h b/src/OpenGL/libGLES_CM/Texture.h index f28022d..ba0c4d5 100644 --- a/src/OpenGL/libGLES_CM/Texture.h +++ b/src/OpenGL/libGLES_CM/Texture.h
@@ -150,7 +150,7 @@ void copyImage(GLint level, GLenum format, GLint x, GLint y, GLsizei width, GLsizei height, Framebuffer *source); void copySubImage(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height, Framebuffer *source); - void setImage(egl::Image *image); + void setSharedImage(egl::Image *image); virtual bool isSamplerComplete() const; virtual bool isCompressed(GLenum target, GLint level) const;
diff --git a/src/OpenGL/libGLES_CM/libGLES_CM.cpp b/src/OpenGL/libGLES_CM/libGLES_CM.cpp index f9c5ab5..bd2de54 100644 --- a/src/OpenGL/libGLES_CM/libGLES_CM.cpp +++ b/src/OpenGL/libGLES_CM/libGLES_CM.cpp
@@ -4623,16 +4623,11 @@ return error(GL_INVALID_ENUM); } - if(!image) - { - return error(GL_INVALID_OPERATION); - } - es1::Context *context = es1::getContext(); if(context) { - es1::Texture2D *texture = 0; + es1::Texture2D *texture = nullptr; switch(target) { @@ -4646,9 +4641,14 @@ return error(GL_INVALID_OPERATION); } - egl::Image *glImage = static_cast<egl::Image*>(image); + egl::Image *eglImage = context->getSharedImage(image); - texture->setImage(glImage); + if(!eglImage) + { + return error(GL_INVALID_OPERATION); + } + + texture->setSharedImage(eglImage); } }
diff --git a/src/OpenGL/libGLESv2/Context.cpp b/src/OpenGL/libGLESv2/Context.cpp index 8583f12..dd44f79 100644 --- a/src/OpenGL/libGLESv2/Context.cpp +++ b/src/OpenGL/libGLESv2/Context.cpp
@@ -4263,7 +4263,12 @@ } else UNREACHABLE(target); - return 0; + return nullptr; +} + +egl::Image *Context::getSharedImage(GLeglImageOES image) +{ + return display->getSharedImage(image); } Device *Context::getDevice()
diff --git a/src/OpenGL/libGLESv2/Context.h b/src/OpenGL/libGLESv2/Context.h index 4750485..bf1f4ae 100644 --- a/src/OpenGL/libGLESv2/Context.h +++ b/src/OpenGL/libGLESv2/Context.h
@@ -688,6 +688,7 @@ virtual void bindTexImage(egl::Surface *surface); virtual EGLenum validateSharedImage(EGLenum target, GLuint name, GLuint textureLevel); virtual egl::Image *createSharedImage(EGLenum target, GLuint name, GLuint textureLevel); + egl::Image *getSharedImage(GLeglImageOES image); Device *getDevice();
diff --git a/src/OpenGL/libGLESv2/Texture.cpp b/src/OpenGL/libGLESv2/Texture.cpp index d1a0cde..50ab54b 100644 --- a/src/OpenGL/libGLESv2/Texture.cpp +++ b/src/OpenGL/libGLESv2/Texture.cpp
@@ -810,7 +810,7 @@ renderTarget->release(); } -void Texture2D::setImage(egl::Image *sharedImage) +void Texture2D::setSharedImage(egl::Image *sharedImage) { if(sharedImage == image[0]) { @@ -1775,7 +1775,7 @@ renderTarget->release(); } -void Texture3D::setImage(egl::Image *sharedImage) +void Texture3D::setSharedImage(egl::Image *sharedImage) { sharedImage->addRef();
diff --git a/src/OpenGL/libGLESv2/Texture.h b/src/OpenGL/libGLESv2/Texture.h index 74452b0..a97f168 100644 --- a/src/OpenGL/libGLESv2/Texture.h +++ b/src/OpenGL/libGLESv2/Texture.h
@@ -175,7 +175,7 @@ void copyImage(GLint level, GLenum format, GLint x, GLint y, GLsizei width, GLsizei height, Framebuffer *source); virtual void copySubImage(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height, Framebuffer *source); - void setImage(egl::Image *image); + void setSharedImage(egl::Image *image); virtual bool isSamplerComplete() const; virtual bool isCompressed(GLenum target, GLint level) const; @@ -295,7 +295,7 @@ void copyImage(GLint level, GLenum format, GLint x, GLint y, GLint z, GLsizei width, GLsizei height, GLsizei depth, Framebuffer *source); void copySubImage(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height, Framebuffer *source); - void setImage(egl::Image *image); + void setSharedImage(egl::Image *image); virtual bool isSamplerComplete() const; virtual bool isCompressed(GLenum target, GLint level) const;
diff --git a/src/OpenGL/libGLESv2/libGLESv2.cpp b/src/OpenGL/libGLESv2/libGLESv2.cpp index ec21154..3e040b4 100644 --- a/src/OpenGL/libGLESv2/libGLESv2.cpp +++ b/src/OpenGL/libGLESv2/libGLESv2.cpp
@@ -35,7 +35,7 @@ #include <limits> -#ifdef ANDROID +#ifdef __ANDROID__ #include <cutils/log.h> #endif @@ -6682,16 +6682,11 @@ return error(GL_INVALID_ENUM); } - if(!image) - { - return error(GL_INVALID_OPERATION); - } - es2::Context *context = es2::getContext(); if(context) { - es2::Texture2D *texture = 0; + es2::Texture2D *texture = nullptr; switch(target) { @@ -6705,9 +6700,14 @@ return error(GL_INVALID_OPERATION); } - egl::Image *glImage = static_cast<egl::Image*>(image); + egl::Image *eglImage = context->getSharedImage(image); - texture->setImage(glImage); + if(!eglImage) + { + return error(GL_INVALID_OPERATION); + } + + texture->setSharedImage(eglImage); } }