Fix validating sync object pointers.
The spec states that "If <sync> is not a valid sync object for <dpy>,
EGL_FALSE is returned and an EGL_BAD_PARAMETER error is generated."
Change-Id: I4bbd2ddfefd7baba9c301decb644bfb545e66f01
Reviewed-on: https://swiftshader-review.googlesource.com/5290
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 cbef7fd..06fb58d 100644
--- a/src/OpenGL/libEGL/Display.cpp
+++ b/src/OpenGL/libEGL/Display.cpp
@@ -444,6 +444,15 @@
return success(context);
}
+EGLSyncKHR Display::createSync(Context *context)
+{
+ FenceSync *fenceSync = new egl::FenceSync(context);
+
+ mSyncSet.insert(fenceSync);
+
+ return fenceSync;
+}
+
void Display::destroySurface(egl::Surface *surface)
{
surface->release();
@@ -473,6 +482,13 @@
}
}
+void Display::destroySync(FenceSync *sync)
+{
+ mSyncSet.erase(sync);
+
+ delete sync;
+}
+
bool Display::isInitialized() const
{
return mConfigSet.size() > 0;
@@ -480,7 +496,7 @@
bool Display::isValidConfig(EGLConfig config)
{
- return mConfigSet.get(config) != NULL;
+ return mConfigSet.get(config) != nullptr;
}
bool Display::isValidContext(egl::Context *context)
@@ -542,6 +558,11 @@
return false;
}
+bool Display::isValidSync(FenceSync *sync)
+{
+ return mSyncSet.find(sync) != mSyncSet.end();
+}
+
EGLint Display::getMinSwapInterval() const
{
return mMinSwapInterval;
diff --git a/src/OpenGL/libEGL/Display.h b/src/OpenGL/libEGL/Display.h
index d08b9a4..3864770 100644
--- a/src/OpenGL/libEGL/Display.h
+++ b/src/OpenGL/libEGL/Display.h
@@ -17,6 +17,7 @@
#define INCLUDE_DISPLAY_H_
#include "Config.h"
+#include "Sync.hpp"
#include <set>
@@ -42,9 +43,11 @@
EGLSurface createWindowSurface(EGLNativeWindowType window, EGLConfig config, const EGLint *attribList);
EGLSurface createPBufferSurface(EGLConfig config, const EGLint *attribList);
EGLContext createContext(EGLConfig configHandle, const Context *shareContext, EGLint clientVersion);
+ EGLSyncKHR createSync(Context *context);
void destroySurface(Surface *surface);
void destroyContext(Context *context);
+ void destroySync(FenceSync *sync);
bool isInitialized() const;
bool isValidConfig(EGLConfig config);
@@ -52,6 +55,7 @@
bool isValidSurface(Surface *surface);
bool isValidWindow(EGLNativeWindowType window);
bool hasExistingWindowSurface(EGLNativeWindowType window);
+ bool isValidSync(FenceSync *sync);
EGLint getMinSwapInterval() const;
EGLint getMaxSwapInterval() const;
@@ -77,6 +81,9 @@
typedef std::set<Context*> ContextSet;
ContextSet mContextSet;
+
+ typedef std::set<FenceSync*> SyncSet;
+ SyncSet mSyncSet;
};
}
diff --git a/src/OpenGL/libEGL/Sync.hpp b/src/OpenGL/libEGL/Sync.hpp
new file mode 100644
index 0000000..c1756ec
--- /dev/null
+++ b/src/OpenGL/libEGL/Sync.hpp
@@ -0,0 +1,50 @@
+// SwiftShader Software Renderer
+//
+// Copyright(c) 2005-2012 TransGaming Inc.
+//
+// All rights reserved. No part of this software may be copied, distributed, transmitted,
+// transcribed, stored in a retrieval system, translated into any human or computer
+// language by any means, or disclosed to third parties without the explicit written
+// agreement of TransGaming Inc. Without such an agreement, no rights or licenses, express
+// or implied, including but not limited to any patent rights, are granted to you.
+//
+
+// Sync.hpp: Defines sync objects for the EGL_KHR_fence_sync extension.
+
+#ifndef LIBEGL_SYNC_H_
+#define LIBEGL_SYNC_H_
+
+#include "Context.hpp"
+
+#include <EGL/eglext.h>
+
+namespace egl
+{
+
+class FenceSync
+{
+public:
+ explicit FenceSync(Context *context) : context(context)
+ {
+ status = EGL_UNSIGNALED_KHR;
+ context->addRef();
+ }
+
+ ~FenceSync()
+ {
+ context->release();
+ context = nullptr;
+ }
+
+ void wait() { context->finish(); signal(); }
+ void signal() { status = EGL_SIGNALED_KHR; }
+ bool isSignaled() const { return status == EGL_SIGNALED_KHR; }
+
+private:
+ EGLint status;
+ Context *context;
+};
+
+}
+
+#endif // LIBEGL_SYNC_H_
diff --git a/src/OpenGL/libEGL/libEGL.cpp b/src/OpenGL/libEGL/libEGL.cpp
index d67d2cc..e54c60f 100644
--- a/src/OpenGL/libEGL/libEGL.cpp
+++ b/src/OpenGL/libEGL/libEGL.cpp
@@ -1017,30 +1017,6 @@
return CreatePixmapSurface(dpy, config, (EGLNativePixmapType)native_pixmap, attrib_list);
}
-class FenceSync
-{
-public:
- explicit FenceSync(Context *context) : context(context)
- {
- status = EGL_UNSIGNALED_KHR;
- context->addRef();
- }
-
- ~FenceSync()
- {
- context->release();
- context = nullptr;
- }
-
- void wait() { context->finish(); signal(); }
- void signal() { status = EGL_SIGNALED_KHR; }
- bool isSignaled() const { return status == EGL_SIGNALED_KHR; }
-
-private:
- EGLint status;
- Context *context;
-};
-
EGLSyncKHR CreateSyncKHR(EGLDisplay dpy, EGLenum type, const EGLint *attrib_list)
{
TRACE("(EGLDisplay dpy = %p, EGLunum type = %x, EGLint *attrib_list=%p)", dpy, type, attrib_list);
@@ -1069,7 +1045,9 @@
return error(EGL_BAD_MATCH, EGL_NO_SYNC_KHR);
}
- return success(new FenceSync(context));
+ EGLSyncKHR sync = display->createSync(context);
+
+ return success(sync);
}
EGLBoolean DestroySyncKHR(EGLDisplay dpy, EGLSyncKHR sync)
@@ -1084,7 +1062,12 @@
return error(EGL_BAD_DISPLAY, EGL_FALSE);
}
- delete eglSync;
+ if(!display->isValidSync(eglSync))
+ {
+ return error(EGL_BAD_PARAMETER, EGL_FALSE);
+ }
+
+ display->destroySync(eglSync);
return success(EGL_TRUE);
}
@@ -1101,6 +1084,11 @@
return error(EGL_BAD_DISPLAY, EGL_FALSE);
}
+ if(!display->isValidSync(eglSync))
+ {
+ return error(EGL_BAD_PARAMETER, EGL_FALSE);
+ }
+
(void)flags;
(void)timeout;
@@ -1117,13 +1105,17 @@
TRACE("(EGLDisplay dpy = %p, EGLSyncKHR sync = %p, EGLint attribute = %x, EGLint *value = %p)", dpy, sync, attribute, value);
egl::Display *display = egl::Display::get(dpy);
+ FenceSync *eglSync = static_cast<FenceSync*>(sync);
if(!validateDisplay(display))
{
return error(EGL_BAD_DISPLAY, EGL_FALSE);
}
- FenceSync *eglSync = static_cast<FenceSync*>(sync);
+ if(!display->isValidSync(eglSync))
+ {
+ return error(EGL_BAD_PARAMETER, EGL_FALSE);
+ }
switch(attribute)
{
diff --git a/src/OpenGL/libEGL/libEGL.vcxproj b/src/OpenGL/libEGL/libEGL.vcxproj
index a01f28c..501d7a1 100644
--- a/src/OpenGL/libEGL/libEGL.vcxproj
+++ b/src/OpenGL/libEGL/libEGL.vcxproj
@@ -319,6 +319,7 @@
<ClInclude Include="main.h" />
<ClInclude Include="resource.h" />
<ClInclude Include="Surface.h" />
+ <ClInclude Include="Sync.hpp" />
<ClInclude Include="Texture.hpp" />
</ItemGroup>
<ItemGroup>
diff --git a/src/OpenGL/libEGL/libEGL.vcxproj.filters b/src/OpenGL/libEGL/libEGL.vcxproj.filters
index 6ec4c50..4400f20 100644
--- a/src/OpenGL/libEGL/libEGL.vcxproj.filters
+++ b/src/OpenGL/libEGL/libEGL.vcxproj.filters
@@ -76,6 +76,9 @@
<ClInclude Include="..\common\Image.hpp">
<Filter>Header Files</Filter>
</ClInclude>
+ <ClInclude Include="Sync.hpp">
+ <Filter>Header Files</Filter>
+ </ClInclude>
</ItemGroup>
<ItemGroup>
<ResourceCompile Include="libEGL.rc" />