summaryrefslogtreecommitdiff
path: root/Userland/Libraries/LibGL
diff options
context:
space:
mode:
authorStephan Unverwerth <s.unverwerth@gmx.de>2021-05-24 16:11:06 +0200
committerLinus Groh <mail@linusgroh.de>2021-05-24 19:03:25 +0100
commitd6c84ca4df9d91f0ab8a871eda228b21893f7371 (patch)
treea7306c0af506fe519622fcf2a275814812dd8b5e /Userland/Libraries/LibGL
parent24e74750d5c31c510bc42b3295f3f618026e57bb (diff)
downloadserenity-d6c84ca4df9d91f0ab8a871eda228b21893f7371.zip
LibGL: Implement glReadPixels() stub with argument validation
Diffstat (limited to 'Userland/Libraries/LibGL')
-rw-r--r--Userland/Libraries/LibGL/GL/gl.h24
-rw-r--r--Userland/Libraries/LibGL/GLContext.h1
-rw-r--r--Userland/Libraries/LibGL/GLUtils.cpp7
-rw-r--r--Userland/Libraries/LibGL/SoftwareGLContext.cpp69
-rw-r--r--Userland/Libraries/LibGL/SoftwareGLContext.h1
5 files changed, 101 insertions, 1 deletions
diff --git a/Userland/Libraries/LibGL/GL/gl.h b/Userland/Libraries/LibGL/GL/gl.h
index b00383a57e..85725e866b 100644
--- a/Userland/Libraries/LibGL/GL/gl.h
+++ b/Userland/Libraries/LibGL/GL/gl.h
@@ -115,6 +115,29 @@ extern "C" {
#define GL_COMPILE 0x1300
#define GL_COMPILE_AND_EXECUTE 0x1301
+// Type enums
+#define GL_BYTE 0x1400
+#define GL_UNSIGNED_BYTE 0x1401
+#define GL_SHORT 0x1402
+#define GL_UNSIGNED_SHORT 0x1403
+#define GL_INT 0x1404
+#define GL_UNSIGNED_INT 0x1405
+#define GL_FLOAT 0x1406
+
+// Format enums
+#define GL_COLOR_INDEX 0x1900
+#define GL_LUMINANCE 0x1909
+#define GL_LUMINANCE_ALPHA 0x190A
+#define GL_BITMAP 0x1A00
+#define GL_STENCIL_INDEX 0x1901
+#define GL_DEPTH_COMPONENT 0x1902
+#define GL_RED 0x1903
+#define GL_GREEN 0x1904
+#define GL_BLUE 0x1905
+#define GL_ALPHA 0x1906
+#define GL_RGB 0x1907
+#define GL_RGBA 0x1908
+
// Lighting related defines
#define GL_FLAT 0x1D00
#define GL_SMOOTH 0x1D01
@@ -211,6 +234,7 @@ GLAPI void glShadeModel(GLenum mode);
GLAPI void glAlphaFunc(GLenum func, GLclampf ref);
GLAPI void glHint(GLenum target, GLenum mode);
GLAPI void glReadBuffer(GLenum mode);
+GLAPI void glReadPixels(GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, GLvoid* pixels);
#ifdef __cplusplus
}
diff --git a/Userland/Libraries/LibGL/GLContext.h b/Userland/Libraries/LibGL/GLContext.h
index c731540c81..191ea58e2c 100644
--- a/Userland/Libraries/LibGL/GLContext.h
+++ b/Userland/Libraries/LibGL/GLContext.h
@@ -54,6 +54,7 @@ public:
virtual void gl_alpha_func(GLenum func, GLclampf ref) = 0;
virtual void gl_hint(GLenum target, GLenum mode) = 0;
virtual void gl_read_buffer(GLenum mode) = 0;
+ virtual void gl_read_pixels(GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, GLvoid* pixels) = 0;
virtual void present() = 0;
};
diff --git a/Userland/Libraries/LibGL/GLUtils.cpp b/Userland/Libraries/LibGL/GLUtils.cpp
index 539aacfb32..1fa3467864 100644
--- a/Userland/Libraries/LibGL/GLUtils.cpp
+++ b/Userland/Libraries/LibGL/GLUtils.cpp
@@ -78,4 +78,9 @@ void glHint(GLenum target, GLenum mode)
void glReadBuffer(GLenum mode)
{
g_gl_context->gl_read_buffer(mode);
-} \ No newline at end of file
+}
+
+void glReadPixels(GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, GLvoid* pixels)
+{
+ g_gl_context->gl_read_pixels(x, y, width, height, format, type, pixels);
+}
diff --git a/Userland/Libraries/LibGL/SoftwareGLContext.cpp b/Userland/Libraries/LibGL/SoftwareGLContext.cpp
index a64d38b427..d985ddd2d0 100644
--- a/Userland/Libraries/LibGL/SoftwareGLContext.cpp
+++ b/Userland/Libraries/LibGL/SoftwareGLContext.cpp
@@ -1050,6 +1050,75 @@ void SoftwareGLContext::gl_read_buffer(GLenum mode)
m_current_read_buffer = mode;
}
+void SoftwareGLContext::gl_read_pixels(GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, GLvoid* pixels)
+{
+ if (m_in_draw_state) {
+ m_error = GL_INVALID_OPERATION;
+ return;
+ }
+
+ // Check for negative width/height omitted because GLsizei is unsigned in our implementation
+
+ if (format != GL_COLOR_INDEX
+ && format != GL_STENCIL_INDEX
+ && format != GL_DEPTH_COMPONENT
+ && format != GL_RED
+ && format != GL_GREEN
+ && format != GL_BLUE
+ && format != GL_ALPHA
+ && format != GL_RGB
+ && format != GL_RGBA
+ && format != GL_LUMINANCE
+ && format != GL_LUMINANCE_ALPHA) {
+ m_error = GL_INVALID_ENUM;
+ return;
+ }
+
+ if (type != GL_UNSIGNED_BYTE
+ && type != GL_BYTE
+ && type != GL_BITMAP
+ && type != GL_UNSIGNED_SHORT
+ && type != GL_SHORT
+ && type != GL_BLUE
+ && type != GL_UNSIGNED_INT
+ && type != GL_INT
+ && type != GL_FLOAT) {
+ m_error = GL_INVALID_ENUM;
+ return;
+ }
+
+ if (format == GL_COLOR_INDEX) {
+ // FIXME: We only support RGBA buffers for now.
+ // Once we add support for indexed color modes do the correct check here
+ m_error = GL_INVALID_OPERATION;
+ return;
+ }
+
+ if (format == GL_STENCIL_INDEX) {
+ // FIXME: We do not have stencil buffers yet
+ // Once we add support for stencil buffers do the correct check here
+ m_error = GL_INVALID_OPERATION;
+ return;
+ }
+
+ if (format == GL_DEPTH_COMPONENT) {
+ // FIXME: This check needs to be a bit more sophisticated. Currently the buffers
+ // are hardcoded. Once we add proper structures for them we need to correct this check
+ if (m_current_read_buffer == GL_FRONT
+ || m_current_read_buffer == GL_FRONT_LEFT
+ || m_current_read_buffer == GL_FRONT_RIGHT) {
+ // Error because only back buffer has a depth buffer
+ m_error = GL_INVALID_OPERATION;
+ return;
+ }
+ }
+
+ if (format == GL_DEPTH_COMPONENT) {
+ // Read from depth buffer
+ return;
+ }
+}
+
void SoftwareGLContext::present()
{
m_rasterizer.blit_to(*m_frontbuffer);
diff --git a/Userland/Libraries/LibGL/SoftwareGLContext.h b/Userland/Libraries/LibGL/SoftwareGLContext.h
index c368979365..4fd041919f 100644
--- a/Userland/Libraries/LibGL/SoftwareGLContext.h
+++ b/Userland/Libraries/LibGL/SoftwareGLContext.h
@@ -60,6 +60,7 @@ public:
virtual void gl_alpha_func(GLenum func, GLclampf ref) override;
virtual void gl_hint(GLenum target, GLenum mode) override;
virtual void gl_read_buffer(GLenum mode) override;
+ virtual void gl_read_pixels(GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, GLvoid* pixels) override;
virtual void present() override;