Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
83 changes: 69 additions & 14 deletions Libraries/LibWeb/WebGL/WebGL2RenderingContextImpl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
* Copyright (c) 2024-2025, Aliaksandr Kalenik <[email protected]>
* Copyright (c) 2024-2025, Luke Wilde <[email protected]>
* Copyright (c) 2025, Jelle Raaijmakers <[email protected]>
* Copyright (c) 2025, Undefine <[email protected]>
*
* SPDX-License-Identifier: BSD-2-Clause
*/
Expand Down Expand Up @@ -228,25 +229,45 @@ void WebGL2RenderingContextImpl::tex_sub_image3d(WebIDL::UnsignedLong target, We
void WebGL2RenderingContextImpl::uniform1ui(GC::Root<WebGLUniformLocation> location, WebIDL::UnsignedLong v0)
{
m_context->make_current();
glUniform1ui(location ? location->handle() : 0, v0);

GLuint location_handle = 0;
if (location)
location_handle = SET_ERROR_VALUE_IF_ERROR(location->handle(m_current_program), GL_INVALID_OPERATION);

glUniform1ui(location_handle, v0);
}

void WebGL2RenderingContextImpl::uniform2ui(GC::Root<WebGLUniformLocation> location, WebIDL::UnsignedLong v0, WebIDL::UnsignedLong v1)
{
m_context->make_current();
glUniform2ui(location ? location->handle() : 0, v0, v1);

GLuint location_handle = 0;
if (location)
location_handle = SET_ERROR_VALUE_IF_ERROR(location->handle(m_current_program), GL_INVALID_OPERATION);

glUniform2ui(location_handle, v0, v1);
}

void WebGL2RenderingContextImpl::uniform3ui(GC::Root<WebGLUniformLocation> location, WebIDL::UnsignedLong v0, WebIDL::UnsignedLong v1, WebIDL::UnsignedLong v2)
{
m_context->make_current();
glUniform3ui(location ? location->handle() : 0, v0, v1, v2);

GLuint location_handle = 0;
if (location)
location_handle = SET_ERROR_VALUE_IF_ERROR(location->handle(m_current_program), GL_INVALID_OPERATION);

glUniform3ui(location_handle, v0, v1, v2);
}

void WebGL2RenderingContextImpl::uniform4ui(GC::Root<WebGLUniformLocation> location, WebIDL::UnsignedLong v0, WebIDL::UnsignedLong v1, WebIDL::UnsignedLong v2, WebIDL::UnsignedLong v3)
{
m_context->make_current();
glUniform4ui(location ? location->handle() : 0, v0, v1, v2, v3);

GLuint location_handle = 0;
if (location)
location_handle = SET_ERROR_VALUE_IF_ERROR(location->handle(m_current_program), GL_INVALID_OPERATION);

glUniform4ui(location_handle, v0, v1, v2, v3);
}

void WebGL2RenderingContextImpl::uniform1uiv(GC::Root<WebGLUniformLocation> location, Uint32List values, WebIDL::UnsignedLongLong src_offset, WebIDL::UnsignedLong src_length)
Expand All @@ -256,8 +277,10 @@ void WebGL2RenderingContextImpl::uniform1uiv(GC::Root<WebGLUniformLocation> loca
if (!location)
return;

GLuint location_handle = SET_ERROR_VALUE_IF_ERROR(location->handle(m_current_program), GL_INVALID_OPERATION);

auto span = SET_ERROR_VALUE_IF_ERROR(span_from_uint32_list(values, src_offset, src_length), GL_INVALID_VALUE);
glUniform1uiv(location->handle(), span.size(), span.data());
glUniform1uiv(location_handle, span.size(), span.data());
}

void WebGL2RenderingContextImpl::uniform2uiv(GC::Root<WebGLUniformLocation> location, Uint32List values, WebIDL::UnsignedLongLong src_offset, WebIDL::UnsignedLong src_length)
Expand All @@ -267,12 +290,14 @@ void WebGL2RenderingContextImpl::uniform2uiv(GC::Root<WebGLUniformLocation> loca
if (!location)
return;

GLuint location_handle = SET_ERROR_VALUE_IF_ERROR(location->handle(m_current_program), GL_INVALID_OPERATION);

auto span = SET_ERROR_VALUE_IF_ERROR(span_from_uint32_list(values, src_offset, src_length), GL_INVALID_VALUE);
if (span.size() % 2 != 0) [[unlikely]] {
set_error(GL_INVALID_VALUE);
return;
}
glUniform2uiv(location->handle(), span.size() / 2, span.data());
glUniform2uiv(location_handle, span.size() / 2, span.data());
}

void WebGL2RenderingContextImpl::uniform3uiv(GC::Root<WebGLUniformLocation> location, Uint32List values, WebIDL::UnsignedLongLong src_offset, WebIDL::UnsignedLong src_length)
Expand All @@ -282,12 +307,14 @@ void WebGL2RenderingContextImpl::uniform3uiv(GC::Root<WebGLUniformLocation> loca
if (!location)
return;

GLuint location_handle = SET_ERROR_VALUE_IF_ERROR(location->handle(m_current_program), GL_INVALID_OPERATION);

auto span = SET_ERROR_VALUE_IF_ERROR(span_from_uint32_list(values, src_offset, src_length), GL_INVALID_VALUE);
if (span.size() % 3 != 0) [[unlikely]] {
set_error(GL_INVALID_VALUE);
return;
}
glUniform3uiv(location->handle(), span.size() / 3, span.data());
glUniform3uiv(location_handle, span.size() / 3, span.data());
}

void WebGL2RenderingContextImpl::uniform4uiv(GC::Root<WebGLUniformLocation> location, Uint32List values, WebIDL::UnsignedLongLong src_offset, WebIDL::UnsignedLong src_length)
Expand All @@ -297,12 +324,14 @@ void WebGL2RenderingContextImpl::uniform4uiv(GC::Root<WebGLUniformLocation> loca
if (!location)
return;

GLuint location_handle = SET_ERROR_VALUE_IF_ERROR(location->handle(m_current_program), GL_INVALID_OPERATION);

auto span = SET_ERROR_VALUE_IF_ERROR(span_from_uint32_list(values, src_offset, src_length), GL_INVALID_VALUE);
if (span.size() % 4 != 0) [[unlikely]] {
set_error(GL_INVALID_VALUE);
return;
}
glUniform4uiv(location->handle(), span.size() / 4, span.data());
glUniform4uiv(location_handle, span.size() / 4, span.data());
}

void WebGL2RenderingContextImpl::uniform_matrix3x2fv(GC::Root<WebGLUniformLocation> location, bool transpose, Float32List data, WebIDL::UnsignedLongLong src_offset, WebIDL::UnsignedLong src_length)
Expand All @@ -312,13 +341,15 @@ void WebGL2RenderingContextImpl::uniform_matrix3x2fv(GC::Root<WebGLUniformLocati
if (!location)
return;

GLuint location_handle = SET_ERROR_VALUE_IF_ERROR(location->handle(m_current_program), GL_INVALID_OPERATION);

constexpr auto matrix_size = 3 * 2;
auto span = SET_ERROR_VALUE_IF_ERROR(span_from_float32_list(data, src_offset, src_length), GL_INVALID_VALUE);
if (span.size() % matrix_size != 0) [[unlikely]] {
set_error(GL_INVALID_VALUE);
return;
}
glUniformMatrix3x2fv(location->handle(), span.size() / matrix_size, transpose, span.data());
glUniformMatrix3x2fv(location_handle, span.size() / matrix_size, transpose, span.data());
}

void WebGL2RenderingContextImpl::uniform_matrix4x2fv(GC::Root<WebGLUniformLocation> location, bool transpose, Float32List data, WebIDL::UnsignedLongLong src_offset, WebIDL::UnsignedLong src_length)
Expand All @@ -328,13 +359,15 @@ void WebGL2RenderingContextImpl::uniform_matrix4x2fv(GC::Root<WebGLUniformLocati
if (!location)
return;

GLuint location_handle = SET_ERROR_VALUE_IF_ERROR(location->handle(m_current_program), GL_INVALID_OPERATION);

constexpr auto matrix_size = 4 * 2;
auto span = SET_ERROR_VALUE_IF_ERROR(span_from_float32_list(data, src_offset, src_length), GL_INVALID_VALUE);
if (span.size() % matrix_size != 0) [[unlikely]] {
set_error(GL_INVALID_VALUE);
return;
}
glUniformMatrix4x2fv(location->handle(), span.size() / matrix_size, transpose, span.data());
glUniformMatrix4x2fv(location_handle, span.size() / matrix_size, transpose, span.data());
}

void WebGL2RenderingContextImpl::uniform_matrix2x3fv(GC::Root<WebGLUniformLocation> location, bool transpose, Float32List data, WebIDL::UnsignedLongLong src_offset, WebIDL::UnsignedLong src_length)
Expand All @@ -344,13 +377,15 @@ void WebGL2RenderingContextImpl::uniform_matrix2x3fv(GC::Root<WebGLUniformLocati
if (!location)
return;

GLuint location_handle = SET_ERROR_VALUE_IF_ERROR(location->handle(m_current_program), GL_INVALID_OPERATION);

constexpr auto matrix_size = 2 * 3;
auto span = SET_ERROR_VALUE_IF_ERROR(span_from_float32_list(data, src_offset, src_length), GL_INVALID_VALUE);
if (span.size() % matrix_size != 0) [[unlikely]] {
set_error(GL_INVALID_VALUE);
return;
}
glUniformMatrix2x3fv(location->handle(), span.size() / matrix_size, transpose, span.data());
glUniformMatrix2x3fv(location_handle, span.size() / matrix_size, transpose, span.data());
}

void WebGL2RenderingContextImpl::uniform_matrix4x3fv(GC::Root<WebGLUniformLocation> location, bool transpose, Float32List data, WebIDL::UnsignedLongLong src_offset, WebIDL::UnsignedLong src_length)
Expand All @@ -360,13 +395,15 @@ void WebGL2RenderingContextImpl::uniform_matrix4x3fv(GC::Root<WebGLUniformLocati
if (!location)
return;

GLuint location_handle = SET_ERROR_VALUE_IF_ERROR(location->handle(m_current_program), GL_INVALID_OPERATION);

constexpr auto matrix_size = 4 * 3;
auto span = SET_ERROR_VALUE_IF_ERROR(span_from_float32_list(data, src_offset, src_length), GL_INVALID_VALUE);
if (span.size() % matrix_size != 0) [[unlikely]] {
set_error(GL_INVALID_VALUE);
return;
}
glUniformMatrix4x3fv(location->handle(), span.size() / matrix_size, transpose, span.data());
glUniformMatrix4x3fv(location_handle, span.size() / matrix_size, transpose, span.data());
}

void WebGL2RenderingContextImpl::uniform_matrix2x4fv(GC::Root<WebGLUniformLocation> location, bool transpose, Float32List data, WebIDL::UnsignedLongLong src_offset, WebIDL::UnsignedLong src_length)
Expand All @@ -376,13 +413,15 @@ void WebGL2RenderingContextImpl::uniform_matrix2x4fv(GC::Root<WebGLUniformLocati
if (!location)
return;

GLuint location_handle = SET_ERROR_VALUE_IF_ERROR(location->handle(m_current_program), GL_INVALID_OPERATION);

constexpr auto matrix_size = 2 * 4;
auto span = SET_ERROR_VALUE_IF_ERROR(span_from_float32_list(data, src_offset, src_length), GL_INVALID_VALUE);
if (span.size() % matrix_size != 0) [[unlikely]] {
set_error(GL_INVALID_VALUE);
return;
}
glUniformMatrix2x4fv(location->handle(), span.size() / matrix_size, transpose, span.data());
glUniformMatrix2x4fv(location_handle, span.size() / matrix_size, transpose, span.data());
}

void WebGL2RenderingContextImpl::uniform_matrix3x4fv(GC::Root<WebGLUniformLocation> location, bool transpose, Float32List data, WebIDL::UnsignedLongLong src_offset, WebIDL::UnsignedLong src_length)
Expand All @@ -392,13 +431,15 @@ void WebGL2RenderingContextImpl::uniform_matrix3x4fv(GC::Root<WebGLUniformLocati
if (!location)
return;

GLuint location_handle = SET_ERROR_VALUE_IF_ERROR(location->handle(m_current_program), GL_INVALID_OPERATION);

constexpr auto matrix_size = 3 * 4;
auto span = SET_ERROR_VALUE_IF_ERROR(span_from_float32_list(data, src_offset, src_length), GL_INVALID_VALUE);
if (span.size() % matrix_size != 0) [[unlikely]] {
set_error(GL_INVALID_VALUE);
return;
}
glUniformMatrix3x4fv(location->handle(), span.size() / matrix_size, transpose, span.data());
glUniformMatrix3x4fv(location_handle, span.size() / matrix_size, transpose, span.data());
}

void WebGL2RenderingContextImpl::vertex_attrib_i4i(WebIDL::UnsignedLong index, WebIDL::Long x, WebIDL::Long y, WebIDL::Long z, WebIDL::Long w)
Expand Down Expand Up @@ -964,6 +1005,11 @@ void WebGL2RenderingContextImpl::bind_buffer_base(WebIDL::UnsignedLong target, W
return;
}
buffer_handle = handle_or_error.release_value();

if (!buffer->is_compatible_with(target)) {
set_error(GL_INVALID_OPERATION);
return;
}
}
glBindBufferBase(target, index, buffer_handle);
}
Expand All @@ -980,6 +1026,11 @@ void WebGL2RenderingContextImpl::bind_buffer_range(WebIDL::UnsignedLong target,
return;
}
buffer_handle = handle_or_error.release_value();

if (!buffer->is_compatible_with(target)) {
set_error(GL_INVALID_OPERATION);
return;
}
}
glBindBufferRange(target, index, buffer_handle, offset, size);
}
Expand Down Expand Up @@ -1157,6 +1208,8 @@ void WebGL2RenderingContextImpl::delete_vertex_array(GC::Root<WebGLVertexArrayOb
}

glDeleteVertexArrays(1, &vertex_array_handle);
if (m_current_vertex_array == vertex_array)
m_current_vertex_array = nullptr;
}

bool WebGL2RenderingContextImpl::is_vertex_array(GC::Root<WebGLVertexArrayObject> vertex_array)
Expand Down Expand Up @@ -1188,7 +1241,9 @@ void WebGL2RenderingContextImpl::bind_vertex_array(GC::Root<WebGLVertexArrayObje
}
array_handle = handle_or_error.release_value();
}

glBindVertexArray(array_handle);
m_current_vertex_array = array;
}

void WebGL2RenderingContextImpl::compressed_tex_image3d(WebIDL::UnsignedLong target, WebIDL::Long level, WebIDL::UnsignedLong internalformat, WebIDL::Long width, WebIDL::Long height, WebIDL::Long depth, WebIDL::Long border, GC::Root<WebIDL::ArrayBufferView> src_data, WebIDL::UnsignedLongLong src_offset, WebIDL::UnsignedLong src_length_override)
Expand Down
Loading
Loading