mirror of
https://github.com/LadybirdBrowser/ladybird.git
synced 2025-12-07 21:59:54 +00:00
LibWeb: Bind WebGL uniform locations to their respective program
The spec mandates that each uniform location object only gets used with the program it was created with.
This commit is contained in:
parent
7d6212ae71
commit
f373ab7011
Notes:
github-actions[bot]
2025-11-27 18:21:14 +00:00
Author: https://github.com/cqundefine
Commit: f373ab7011
Pull-request: https://github.com/LadybirdBrowser/ladybird/pull/6744
Reviewed-by: https://github.com/gmta ✅
Reviewed-by: https://github.com/konradekk
6 changed files with 209 additions and 51 deletions
|
|
@ -229,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)
|
||||
|
|
@ -257,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)
|
||||
|
|
@ -268,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)
|
||||
|
|
@ -283,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)
|
||||
|
|
@ -298,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)
|
||||
|
|
@ -313,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)
|
||||
|
|
@ -329,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)
|
||||
|
|
@ -345,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)
|
||||
|
|
@ -361,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)
|
||||
|
|
@ -377,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)
|
||||
|
|
@ -393,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)
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@
|
|||
* Copyright (c) 2024-2025, Aliaksandr Kalenik <kalenik.aliaksandr@gmail.com>
|
||||
* Copyright (c) 2024-2025, Luke Wilde <luke@ladybird.org>
|
||||
* Copyright (c) 2025, Jelle Raaijmakers <jelle@ladybird.org>
|
||||
* Copyright (c) 2025, Undefine <undefine@undefine.pl>
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-2-Clause
|
||||
*/
|
||||
|
|
@ -195,8 +196,10 @@ void WebGL2RenderingContextOverloads::uniform1fv(GC::Root<WebGLUniformLocation>
|
|||
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_float32_list(values, src_offset, src_length), GL_INVALID_VALUE);
|
||||
glUniform1fv(location->handle(), span.size(), span.data());
|
||||
glUniform1fv(location_handle, span.size(), span.data());
|
||||
}
|
||||
|
||||
void WebGL2RenderingContextOverloads::uniform2fv(GC::Root<WebGLUniformLocation> location, Float32List values, WebIDL::UnsignedLongLong src_offset, WebIDL::UnsignedLong src_length)
|
||||
|
|
@ -206,12 +209,14 @@ void WebGL2RenderingContextOverloads::uniform2fv(GC::Root<WebGLUniformLocation>
|
|||
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_float32_list(values, src_offset, src_length), GL_INVALID_VALUE);
|
||||
if (span.size() % 2 != 0) [[unlikely]] {
|
||||
set_error(GL_INVALID_VALUE);
|
||||
return;
|
||||
}
|
||||
glUniform2fv(location->handle(), span.size() / 2, span.data());
|
||||
glUniform2fv(location_handle, span.size() / 2, span.data());
|
||||
}
|
||||
|
||||
void WebGL2RenderingContextOverloads::uniform3fv(GC::Root<WebGLUniformLocation> location, Float32List values, WebIDL::UnsignedLongLong src_offset, WebIDL::UnsignedLong src_length)
|
||||
|
|
@ -221,12 +226,14 @@ void WebGL2RenderingContextOverloads::uniform3fv(GC::Root<WebGLUniformLocation>
|
|||
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_float32_list(values, src_offset, src_length), GL_INVALID_VALUE);
|
||||
if (span.size() % 3 != 0) [[unlikely]] {
|
||||
set_error(GL_INVALID_VALUE);
|
||||
return;
|
||||
}
|
||||
glUniform3fv(location->handle(), span.size() / 3, span.data());
|
||||
glUniform3fv(location_handle, span.size() / 3, span.data());
|
||||
}
|
||||
|
||||
void WebGL2RenderingContextOverloads::uniform4fv(GC::Root<WebGLUniformLocation> location, Float32List values, WebIDL::UnsignedLongLong src_offset, WebIDL::UnsignedLong src_length)
|
||||
|
|
@ -236,12 +243,14 @@ void WebGL2RenderingContextOverloads::uniform4fv(GC::Root<WebGLUniformLocation>
|
|||
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_float32_list(values, src_offset, src_length), GL_INVALID_VALUE);
|
||||
if (span.size() % 4 != 0) [[unlikely]] {
|
||||
set_error(GL_INVALID_VALUE);
|
||||
return;
|
||||
}
|
||||
glUniform4fv(location->handle(), span.size() / 4, span.data());
|
||||
glUniform4fv(location_handle, span.size() / 4, span.data());
|
||||
}
|
||||
|
||||
void WebGL2RenderingContextOverloads::uniform1iv(GC::Root<WebGLUniformLocation> location, Int32List values, WebIDL::UnsignedLongLong src_offset, WebIDL::UnsignedLong src_length)
|
||||
|
|
@ -251,8 +260,10 @@ void WebGL2RenderingContextOverloads::uniform1iv(GC::Root<WebGLUniformLocation>
|
|||
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_int32_list(values, src_offset, src_length), GL_INVALID_VALUE);
|
||||
glUniform1iv(location->handle(), span.size(), span.data());
|
||||
glUniform1iv(location_handle, span.size(), span.data());
|
||||
}
|
||||
|
||||
void WebGL2RenderingContextOverloads::uniform2iv(GC::Root<WebGLUniformLocation> location, Int32List values, WebIDL::UnsignedLongLong src_offset, WebIDL::UnsignedLong src_length)
|
||||
|
|
@ -262,12 +273,14 @@ void WebGL2RenderingContextOverloads::uniform2iv(GC::Root<WebGLUniformLocation>
|
|||
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_int32_list(values, src_offset, src_length), GL_INVALID_VALUE);
|
||||
if (span.size() % 2 != 0) [[unlikely]] {
|
||||
set_error(GL_INVALID_VALUE);
|
||||
return;
|
||||
}
|
||||
glUniform2iv(location->handle(), span.size() / 2, span.data());
|
||||
glUniform2iv(location_handle, span.size() / 2, span.data());
|
||||
}
|
||||
|
||||
void WebGL2RenderingContextOverloads::uniform3iv(GC::Root<WebGLUniformLocation> location, Int32List values, WebIDL::UnsignedLongLong src_offset, WebIDL::UnsignedLong src_length)
|
||||
|
|
@ -277,12 +290,14 @@ void WebGL2RenderingContextOverloads::uniform3iv(GC::Root<WebGLUniformLocation>
|
|||
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_int32_list(values, src_offset, src_length), GL_INVALID_VALUE);
|
||||
if (span.size() % 3 != 0) [[unlikely]] {
|
||||
set_error(GL_INVALID_VALUE);
|
||||
return;
|
||||
}
|
||||
glUniform3iv(location->handle(), span.size() / 3, span.data());
|
||||
glUniform3iv(location_handle, span.size() / 3, span.data());
|
||||
}
|
||||
|
||||
void WebGL2RenderingContextOverloads::uniform4iv(GC::Root<WebGLUniformLocation> location, Int32List values, WebIDL::UnsignedLongLong src_offset, WebIDL::UnsignedLong src_length)
|
||||
|
|
@ -292,12 +307,14 @@ void WebGL2RenderingContextOverloads::uniform4iv(GC::Root<WebGLUniformLocation>
|
|||
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_int32_list(values, src_offset, src_length), GL_INVALID_VALUE);
|
||||
if (span.size() % 4 != 0) [[unlikely]] {
|
||||
set_error(GL_INVALID_VALUE);
|
||||
return;
|
||||
}
|
||||
glUniform4iv(location->handle(), span.size() / 4, span.data());
|
||||
glUniform4iv(location_handle, span.size() / 4, span.data());
|
||||
}
|
||||
|
||||
void WebGL2RenderingContextOverloads::uniform_matrix2fv(GC::Root<WebGLUniformLocation> location, bool transpose, Float32List data, WebIDL::UnsignedLongLong src_offset, WebIDL::UnsignedLong src_length)
|
||||
|
|
@ -307,13 +324,15 @@ void WebGL2RenderingContextOverloads::uniform_matrix2fv(GC::Root<WebGLUniformLoc
|
|||
if (!location)
|
||||
return;
|
||||
|
||||
GLuint location_handle = SET_ERROR_VALUE_IF_ERROR(location->handle(m_current_program), GL_INVALID_OPERATION);
|
||||
|
||||
constexpr auto matrix_size = 2 * 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;
|
||||
}
|
||||
glUniformMatrix2fv(location->handle(), span.size() / matrix_size, transpose, span.data());
|
||||
glUniformMatrix2fv(location_handle, span.size() / matrix_size, transpose, span.data());
|
||||
}
|
||||
|
||||
void WebGL2RenderingContextOverloads::uniform_matrix3fv(GC::Root<WebGLUniformLocation> location, bool transpose, Float32List data, WebIDL::UnsignedLongLong src_offset, WebIDL::UnsignedLong src_length)
|
||||
|
|
@ -323,13 +342,15 @@ void WebGL2RenderingContextOverloads::uniform_matrix3fv(GC::Root<WebGLUniformLoc
|
|||
if (!location)
|
||||
return;
|
||||
|
||||
GLuint location_handle = SET_ERROR_VALUE_IF_ERROR(location->handle(m_current_program), GL_INVALID_OPERATION);
|
||||
|
||||
constexpr auto matrix_size = 3 * 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;
|
||||
}
|
||||
glUniformMatrix3fv(location->handle(), span.size() / matrix_size, transpose, span.data());
|
||||
glUniformMatrix3fv(location_handle, span.size() / matrix_size, transpose, span.data());
|
||||
}
|
||||
|
||||
void WebGL2RenderingContextOverloads::uniform_matrix4fv(GC::Root<WebGLUniformLocation> location, bool transpose, Float32List data, WebIDL::UnsignedLongLong src_offset, WebIDL::UnsignedLong src_length)
|
||||
|
|
@ -339,13 +360,15 @@ void WebGL2RenderingContextOverloads::uniform_matrix4fv(GC::Root<WebGLUniformLoc
|
|||
if (!location)
|
||||
return;
|
||||
|
||||
GLuint location_handle = SET_ERROR_VALUE_IF_ERROR(location->handle(m_current_program), GL_INVALID_OPERATION);
|
||||
|
||||
constexpr auto matrix_size = 4 * 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;
|
||||
}
|
||||
glUniformMatrix4fv(location->handle(), span.size() / matrix_size, transpose, span.data());
|
||||
glUniformMatrix4fv(location_handle, span.size() / matrix_size, transpose, span.data());
|
||||
}
|
||||
|
||||
void WebGL2RenderingContextOverloads::read_pixels(WebIDL::Long x, WebIDL::Long y, WebIDL::Long width, WebIDL::Long height, WebIDL::UnsignedLong format, WebIDL::UnsignedLong type, GC::Root<WebIDL::ArrayBufferView> pixels)
|
||||
|
|
|
|||
|
|
@ -1751,7 +1751,7 @@ GC::Root<WebGLUniformLocation> WebGLRenderingContextImpl::get_uniform_location(G
|
|||
if (location == -1)
|
||||
return nullptr;
|
||||
|
||||
return WebGLUniformLocation::create(m_realm, location);
|
||||
return WebGLUniformLocation::create(m_realm, location, program.ptr());
|
||||
}
|
||||
|
||||
JS::Value WebGLRenderingContextImpl::get_vertex_attrib(WebIDL::UnsignedLong index, WebIDL::UnsignedLong pname)
|
||||
|
|
@ -2082,49 +2082,89 @@ void WebGLRenderingContextImpl::tex_parameteri(WebIDL::UnsignedLong target, WebI
|
|||
void WebGLRenderingContextImpl::uniform1f(GC::Root<WebGLUniformLocation> location, float x)
|
||||
{
|
||||
m_context->make_current();
|
||||
glUniform1f(location ? location->handle() : 0, x);
|
||||
|
||||
GLuint location_handle = 0;
|
||||
if (location)
|
||||
location_handle = SET_ERROR_VALUE_IF_ERROR(location->handle(m_current_program), GL_INVALID_OPERATION);
|
||||
|
||||
glUniform1f(location_handle, x);
|
||||
}
|
||||
|
||||
void WebGLRenderingContextImpl::uniform2f(GC::Root<WebGLUniformLocation> location, float x, float y)
|
||||
{
|
||||
m_context->make_current();
|
||||
glUniform2f(location ? location->handle() : 0, x, y);
|
||||
|
||||
GLuint location_handle = 0;
|
||||
if (location)
|
||||
location_handle = SET_ERROR_VALUE_IF_ERROR(location->handle(m_current_program), GL_INVALID_OPERATION);
|
||||
|
||||
glUniform2f(location_handle, x, y);
|
||||
}
|
||||
|
||||
void WebGLRenderingContextImpl::uniform3f(GC::Root<WebGLUniformLocation> location, float x, float y, float z)
|
||||
{
|
||||
m_context->make_current();
|
||||
glUniform3f(location ? location->handle() : 0, x, y, z);
|
||||
|
||||
GLuint location_handle = 0;
|
||||
if (location)
|
||||
location_handle = SET_ERROR_VALUE_IF_ERROR(location->handle(m_current_program), GL_INVALID_OPERATION);
|
||||
|
||||
glUniform3f(location_handle, x, y, z);
|
||||
}
|
||||
|
||||
void WebGLRenderingContextImpl::uniform4f(GC::Root<WebGLUniformLocation> location, float x, float y, float z, float w)
|
||||
{
|
||||
m_context->make_current();
|
||||
glUniform4f(location ? location->handle() : 0, x, y, z, w);
|
||||
|
||||
GLuint location_handle = 0;
|
||||
if (location)
|
||||
location_handle = SET_ERROR_VALUE_IF_ERROR(location->handle(m_current_program), GL_INVALID_OPERATION);
|
||||
|
||||
glUniform4f(location_handle, x, y, z, w);
|
||||
}
|
||||
|
||||
void WebGLRenderingContextImpl::uniform1i(GC::Root<WebGLUniformLocation> location, WebIDL::Long x)
|
||||
{
|
||||
m_context->make_current();
|
||||
glUniform1i(location ? location->handle() : 0, x);
|
||||
|
||||
GLuint location_handle = 0;
|
||||
if (location)
|
||||
location_handle = SET_ERROR_VALUE_IF_ERROR(location->handle(m_current_program), GL_INVALID_OPERATION);
|
||||
|
||||
glUniform1i(location_handle, x);
|
||||
}
|
||||
|
||||
void WebGLRenderingContextImpl::uniform2i(GC::Root<WebGLUniformLocation> location, WebIDL::Long x, WebIDL::Long y)
|
||||
{
|
||||
m_context->make_current();
|
||||
glUniform2i(location ? location->handle() : 0, x, y);
|
||||
|
||||
GLuint location_handle = 0;
|
||||
if (location)
|
||||
location_handle = SET_ERROR_VALUE_IF_ERROR(location->handle(m_current_program), GL_INVALID_OPERATION);
|
||||
|
||||
glUniform2i(location_handle, x, y);
|
||||
}
|
||||
|
||||
void WebGLRenderingContextImpl::uniform3i(GC::Root<WebGLUniformLocation> location, WebIDL::Long x, WebIDL::Long y, WebIDL::Long z)
|
||||
{
|
||||
m_context->make_current();
|
||||
glUniform3i(location ? location->handle() : 0, x, y, z);
|
||||
|
||||
GLuint location_handle = 0;
|
||||
if (location)
|
||||
location_handle = SET_ERROR_VALUE_IF_ERROR(location->handle(m_current_program), GL_INVALID_OPERATION);
|
||||
|
||||
glUniform3i(location_handle, x, y, z);
|
||||
}
|
||||
|
||||
void WebGLRenderingContextImpl::uniform4i(GC::Root<WebGLUniformLocation> location, WebIDL::Long x, WebIDL::Long y, WebIDL::Long z, WebIDL::Long w)
|
||||
{
|
||||
m_context->make_current();
|
||||
glUniform4i(location ? location->handle() : 0, x, y, z, w);
|
||||
|
||||
GLuint location_handle = 0;
|
||||
if (location)
|
||||
location_handle = SET_ERROR_VALUE_IF_ERROR(location->handle(m_current_program), GL_INVALID_OPERATION);
|
||||
|
||||
glUniform4i(location_handle, x, y, z, w);
|
||||
}
|
||||
|
||||
void WebGLRenderingContextImpl::use_program(GC::Root<WebGLProgram> program)
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
/*
|
||||
* Copyright (c) 2024-2025, Aliaksandr Kalenik <kalenik.aliaksandr@gmail.com>
|
||||
* Copyright (c) 2024-2025, Luke Wilde <luke@ladybird.org>
|
||||
* Copyright (c) 2025, Undefine <undefine@undefine.pl>
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-2-Clause
|
||||
*/
|
||||
|
|
@ -192,8 +193,11 @@ void WebGLRenderingContextOverloads::uniform1fv(GC::Root<WebGLUniformLocation> l
|
|||
|
||||
if (!location)
|
||||
return;
|
||||
|
||||
GLuint location_handle = SET_ERROR_VALUE_IF_ERROR(location->handle(m_current_program), GL_INVALID_OPERATION);
|
||||
|
||||
auto span = MUST(span_from_float32_list(v, /* src_offset= */ 0));
|
||||
glUniform1fv(location->handle(), span.size(), span.data());
|
||||
glUniform1fv(location_handle, span.size(), span.data());
|
||||
}
|
||||
|
||||
void WebGLRenderingContextOverloads::uniform2fv(GC::Root<WebGLUniformLocation> location, Float32List v)
|
||||
|
|
@ -202,12 +206,15 @@ void WebGLRenderingContextOverloads::uniform2fv(GC::Root<WebGLUniformLocation> l
|
|||
|
||||
if (!location)
|
||||
return;
|
||||
|
||||
GLuint location_handle = SET_ERROR_VALUE_IF_ERROR(location->handle(m_current_program), GL_INVALID_OPERATION);
|
||||
|
||||
auto span = MUST(span_from_float32_list(v, /* src_offset= */ 0));
|
||||
if (span.size() % 2 != 0) [[unlikely]] {
|
||||
set_error(GL_INVALID_VALUE);
|
||||
return;
|
||||
}
|
||||
glUniform2fv(location->handle(), span.size() / 2, span.data());
|
||||
glUniform2fv(location_handle, span.size() / 2, span.data());
|
||||
}
|
||||
|
||||
void WebGLRenderingContextOverloads::uniform3fv(GC::Root<WebGLUniformLocation> location, Float32List v)
|
||||
|
|
@ -216,12 +223,15 @@ void WebGLRenderingContextOverloads::uniform3fv(GC::Root<WebGLUniformLocation> l
|
|||
|
||||
if (!location)
|
||||
return;
|
||||
|
||||
GLuint location_handle = SET_ERROR_VALUE_IF_ERROR(location->handle(m_current_program), GL_INVALID_OPERATION);
|
||||
|
||||
auto span = MUST(span_from_float32_list(v, /* src_offset= */ 0));
|
||||
if (span.size() % 3 != 0) [[unlikely]] {
|
||||
set_error(GL_INVALID_VALUE);
|
||||
return;
|
||||
}
|
||||
glUniform3fv(location->handle(), span.size() / 3, span.data());
|
||||
glUniform3fv(location_handle, span.size() / 3, span.data());
|
||||
}
|
||||
|
||||
void WebGLRenderingContextOverloads::uniform4fv(GC::Root<WebGLUniformLocation> location, Float32List v)
|
||||
|
|
@ -230,12 +240,15 @@ void WebGLRenderingContextOverloads::uniform4fv(GC::Root<WebGLUniformLocation> l
|
|||
|
||||
if (!location)
|
||||
return;
|
||||
|
||||
GLuint location_handle = SET_ERROR_VALUE_IF_ERROR(location->handle(m_current_program), GL_INVALID_OPERATION);
|
||||
|
||||
auto span = MUST(span_from_float32_list(v, /* src_offset= */ 0));
|
||||
if (span.size() % 4 != 0) [[unlikely]] {
|
||||
set_error(GL_INVALID_VALUE);
|
||||
return;
|
||||
}
|
||||
glUniform4fv(location->handle(), span.size() / 4, span.data());
|
||||
glUniform4fv(location_handle, span.size() / 4, span.data());
|
||||
}
|
||||
|
||||
void WebGLRenderingContextOverloads::uniform1iv(GC::Root<WebGLUniformLocation> location, Int32List v)
|
||||
|
|
@ -244,8 +257,11 @@ void WebGLRenderingContextOverloads::uniform1iv(GC::Root<WebGLUniformLocation> l
|
|||
|
||||
if (!location)
|
||||
return;
|
||||
|
||||
GLuint location_handle = SET_ERROR_VALUE_IF_ERROR(location->handle(m_current_program), GL_INVALID_OPERATION);
|
||||
|
||||
auto span = MUST(span_from_int32_list(v, /* src_offset= */ 0));
|
||||
glUniform1iv(location->handle(), span.size(), span.data());
|
||||
glUniform1iv(location_handle, span.size(), span.data());
|
||||
}
|
||||
|
||||
void WebGLRenderingContextOverloads::uniform2iv(GC::Root<WebGLUniformLocation> location, Int32List v)
|
||||
|
|
@ -254,12 +270,15 @@ void WebGLRenderingContextOverloads::uniform2iv(GC::Root<WebGLUniformLocation> l
|
|||
|
||||
if (!location)
|
||||
return;
|
||||
|
||||
GLuint location_handle = SET_ERROR_VALUE_IF_ERROR(location->handle(m_current_program), GL_INVALID_OPERATION);
|
||||
|
||||
auto span = MUST(span_from_int32_list(v, /* src_offset= */ 0));
|
||||
if (span.size() % 2 != 0) [[unlikely]] {
|
||||
set_error(GL_INVALID_VALUE);
|
||||
return;
|
||||
}
|
||||
glUniform2iv(location->handle(), span.size() / 2, span.data());
|
||||
glUniform2iv(location_handle, span.size() / 2, span.data());
|
||||
}
|
||||
|
||||
void WebGLRenderingContextOverloads::uniform3iv(GC::Root<WebGLUniformLocation> location, Int32List v)
|
||||
|
|
@ -268,12 +287,15 @@ void WebGLRenderingContextOverloads::uniform3iv(GC::Root<WebGLUniformLocation> l
|
|||
|
||||
if (!location)
|
||||
return;
|
||||
|
||||
GLuint location_handle = SET_ERROR_VALUE_IF_ERROR(location->handle(m_current_program), GL_INVALID_OPERATION);
|
||||
|
||||
auto span = MUST(span_from_int32_list(v, /* src_offset= */ 0));
|
||||
if (span.size() % 3 != 0) [[unlikely]] {
|
||||
set_error(GL_INVALID_VALUE);
|
||||
return;
|
||||
}
|
||||
glUniform3iv(location->handle(), span.size() / 3, span.data());
|
||||
glUniform3iv(location_handle, span.size() / 3, span.data());
|
||||
}
|
||||
|
||||
void WebGLRenderingContextOverloads::uniform4iv(GC::Root<WebGLUniformLocation> location, Int32List v)
|
||||
|
|
@ -282,12 +304,15 @@ void WebGLRenderingContextOverloads::uniform4iv(GC::Root<WebGLUniformLocation> l
|
|||
|
||||
if (!location)
|
||||
return;
|
||||
|
||||
GLuint location_handle = SET_ERROR_VALUE_IF_ERROR(location->handle(m_current_program), GL_INVALID_OPERATION);
|
||||
|
||||
auto span = MUST(span_from_int32_list(v, /* src_offset= */ 0));
|
||||
if (span.size() % 4 != 0) [[unlikely]] {
|
||||
set_error(GL_INVALID_VALUE);
|
||||
return;
|
||||
}
|
||||
glUniform4iv(location->handle(), span.size() / 4, span.data());
|
||||
glUniform4iv(location_handle, span.size() / 4, span.data());
|
||||
}
|
||||
|
||||
void WebGLRenderingContextOverloads::uniform_matrix2fv(GC::Root<WebGLUniformLocation> location, bool transpose, Float32List value)
|
||||
|
|
@ -296,13 +321,16 @@ void WebGLRenderingContextOverloads::uniform_matrix2fv(GC::Root<WebGLUniformLoca
|
|||
|
||||
if (!location)
|
||||
return;
|
||||
|
||||
GLuint location_handle = SET_ERROR_VALUE_IF_ERROR(location->handle(m_current_program), GL_INVALID_OPERATION);
|
||||
|
||||
constexpr auto matrix_size = 2 * 2;
|
||||
auto span = MUST(span_from_float32_list(value, /* src_offset= */ 0));
|
||||
if (span.size() % matrix_size != 0) [[unlikely]] {
|
||||
set_error(GL_INVALID_VALUE);
|
||||
return;
|
||||
}
|
||||
glUniformMatrix2fv(location->handle(), span.size() / matrix_size, transpose, span.data());
|
||||
glUniformMatrix2fv(location_handle, span.size() / matrix_size, transpose, span.data());
|
||||
}
|
||||
|
||||
void WebGLRenderingContextOverloads::uniform_matrix3fv(GC::Root<WebGLUniformLocation> location, bool transpose, Float32List value)
|
||||
|
|
@ -311,13 +339,16 @@ void WebGLRenderingContextOverloads::uniform_matrix3fv(GC::Root<WebGLUniformLoca
|
|||
|
||||
if (!location)
|
||||
return;
|
||||
|
||||
GLuint location_handle = SET_ERROR_VALUE_IF_ERROR(location->handle(m_current_program), GL_INVALID_OPERATION);
|
||||
|
||||
constexpr auto matrix_size = 3 * 3;
|
||||
auto span = MUST(span_from_float32_list(value, /* src_offset= */ 0));
|
||||
if (span.size() % matrix_size != 0) [[unlikely]] {
|
||||
set_error(GL_INVALID_VALUE);
|
||||
return;
|
||||
}
|
||||
glUniformMatrix3fv(location->handle(), span.size() / matrix_size, transpose, span.data());
|
||||
glUniformMatrix3fv(location_handle, span.size() / matrix_size, transpose, span.data());
|
||||
}
|
||||
|
||||
void WebGLRenderingContextOverloads::uniform_matrix4fv(GC::Root<WebGLUniformLocation> location, bool transpose, Float32List value)
|
||||
|
|
@ -326,13 +357,16 @@ void WebGLRenderingContextOverloads::uniform_matrix4fv(GC::Root<WebGLUniformLoca
|
|||
|
||||
if (!location)
|
||||
return;
|
||||
|
||||
GLuint location_handle = SET_ERROR_VALUE_IF_ERROR(location->handle(m_current_program), GL_INVALID_OPERATION);
|
||||
|
||||
constexpr auto matrix_size = 4 * 4;
|
||||
auto span = MUST(span_from_float32_list(value, /* src_offset= */ 0));
|
||||
if (span.size() % matrix_size != 0) [[unlikely]] {
|
||||
set_error(GL_INVALID_VALUE);
|
||||
return;
|
||||
}
|
||||
glUniformMatrix4fv(location->handle(), span.size() / matrix_size, transpose, span.data());
|
||||
glUniformMatrix4fv(location_handle, span.size() / matrix_size, transpose, span.data());
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@
|
|||
* Copyright (c) 2024, Jelle Raaijmakers <jelle@ladybird.org>
|
||||
* Copyright (c) 2024, Aliaksandr Kalenik <kalenik.aliaksandr@gmail.com>
|
||||
* Copyright (c) 2024, Luke Wilde <luke@ladybird.org>
|
||||
* Copyright (c) 2025, Undefine <undefine@undefine.pl>
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-2-Clause
|
||||
*/
|
||||
|
|
@ -11,18 +12,21 @@
|
|||
#include <LibWeb/Bindings/WebGLUniformLocationPrototype.h>
|
||||
#include <LibWeb/WebGL/WebGLUniformLocation.h>
|
||||
|
||||
#include <GLES2/gl2.h>
|
||||
|
||||
namespace Web::WebGL {
|
||||
|
||||
GC_DEFINE_ALLOCATOR(WebGLUniformLocation);
|
||||
|
||||
GC::Ref<WebGLUniformLocation> WebGLUniformLocation::create(JS::Realm& realm, GLuint handle)
|
||||
GC::Ref<WebGLUniformLocation> WebGLUniformLocation::create(JS::Realm& realm, GLuint handle, GC::Ptr<WebGLProgram> parent_shader)
|
||||
{
|
||||
return realm.create<WebGLUniformLocation>(realm, handle);
|
||||
return realm.create<WebGLUniformLocation>(realm, handle, parent_shader);
|
||||
}
|
||||
|
||||
WebGLUniformLocation::WebGLUniformLocation(JS::Realm& realm, GLuint handle)
|
||||
WebGLUniformLocation::WebGLUniformLocation(JS::Realm& realm, GLuint handle, GC::Ptr<WebGLProgram> parent_shader)
|
||||
: Bindings::PlatformObject(realm)
|
||||
, m_handle(handle)
|
||||
, m_parent_shader(parent_shader)
|
||||
{
|
||||
}
|
||||
|
||||
|
|
@ -34,4 +38,17 @@ void WebGLUniformLocation::initialize(JS::Realm& realm)
|
|||
Base::initialize(realm);
|
||||
}
|
||||
|
||||
void WebGLUniformLocation::visit_edges(Cell::Visitor& visitor)
|
||||
{
|
||||
Base::visit_edges(visitor);
|
||||
visitor.visit(m_parent_shader);
|
||||
}
|
||||
|
||||
ErrorOr<GLuint> WebGLUniformLocation::handle(GC::Ptr<WebGLProgram> current_shader) const
|
||||
{
|
||||
if (current_shader == m_parent_shader)
|
||||
return m_handle;
|
||||
return Error::from_errno(GL_INVALID_OPERATION);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
/*
|
||||
* Copyright (c) 2024, Jelle Raaijmakers <jelle@ladybird.org>
|
||||
* Copyright (c) 2024, Aliaksandr Kalenik <kalenik.aliaksandr@gmail.com>
|
||||
* Copyright (c) 2025, Undefine <undefine@undefine.pl>
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-2-Clause
|
||||
*/
|
||||
|
|
@ -9,6 +10,7 @@
|
|||
|
||||
#include <LibWeb/Bindings/PlatformObject.h>
|
||||
#include <LibWeb/WebGL/Types.h>
|
||||
#include <LibWeb/WebGL/WebGLProgram.h>
|
||||
|
||||
namespace Web::WebGL {
|
||||
|
||||
|
|
@ -17,18 +19,20 @@ class WebGLUniformLocation final : public Bindings::PlatformObject {
|
|||
GC_DECLARE_ALLOCATOR(WebGLUniformLocation);
|
||||
|
||||
public:
|
||||
static GC::Ref<WebGLUniformLocation> create(JS::Realm& realm, GLuint handle);
|
||||
static GC::Ref<WebGLUniformLocation> create(JS::Realm& realm, GLuint handle, GC::Ptr<WebGLProgram> parent_shader);
|
||||
|
||||
virtual ~WebGLUniformLocation();
|
||||
|
||||
GLuint handle() const { return m_handle; }
|
||||
ErrorOr<GLuint> handle(GC::Ptr<WebGLProgram> current_shader) const;
|
||||
|
||||
protected:
|
||||
explicit WebGLUniformLocation(JS::Realm&, GLuint handle);
|
||||
explicit WebGLUniformLocation(JS::Realm&, GLuint handle, GC::Ptr<WebGLProgram> parent_shader);
|
||||
|
||||
virtual void initialize(JS::Realm&) override;
|
||||
virtual void visit_edges(JS::Cell::Visitor&) override;
|
||||
|
||||
GLuint m_handle { 0 };
|
||||
GC::Ptr<WebGLProgram> m_parent_shader;
|
||||
};
|
||||
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue