mirror of
https://github.com/zebrajr/ladybird.git
synced 2025-12-06 00:19:53 +01:00
LibWeb/WebGL: Replace manual pointer math with Span
This deduplicates a lot of sensitive pointer math by using Span, which performs this math for us with more safety checks and with type information. This also allows us to use the correctly typed Span for typed arrays, which automatically fixes srcOffset to now offset by the number of elements instead of bytes. This goes for srcLengthOverride too. Fixes the Rive animations on Shopify's homepage not appearing. Fixes some Unity applications such as ArcViewer having missing graphics.
This commit is contained in:
parent
afd170d16c
commit
ab3eb9adab
|
|
@ -32,6 +32,16 @@ extern "C" {
|
||||||
#include <LibWeb/WebGL/WebGLVertexArrayObject.h>
|
#include <LibWeb/WebGL/WebGLVertexArrayObject.h>
|
||||||
#include <LibWeb/WebIDL/Buffers.h>
|
#include <LibWeb/WebIDL/Buffers.h>
|
||||||
|
|
||||||
|
#define SET_ERROR_VALUE_IF_ERROR(expression, error_value) \
|
||||||
|
({ \
|
||||||
|
auto maybe_error = expression; \
|
||||||
|
if (maybe_error.is_error()) [[unlikely]] { \
|
||||||
|
set_error(error_value); \
|
||||||
|
return; \
|
||||||
|
} \
|
||||||
|
maybe_error.release_value(); \
|
||||||
|
})
|
||||||
|
|
||||||
namespace Web::WebGL {
|
namespace Web::WebGL {
|
||||||
|
|
||||||
static Vector<GLchar> null_terminated_string(StringView string)
|
static Vector<GLchar> null_terminated_string(StringView string)
|
||||||
|
|
@ -122,45 +132,36 @@ void WebGL2RenderingContextImpl::tex_image3d(WebIDL::UnsignedLong target, WebIDL
|
||||||
{
|
{
|
||||||
m_context->make_current();
|
m_context->make_current();
|
||||||
|
|
||||||
void const* src_data_ptr = nullptr;
|
ReadonlyBytes src_data_span;
|
||||||
size_t buffer_size = 0;
|
|
||||||
if (src_data) {
|
if (src_data) {
|
||||||
auto const& viewed_array_buffer = src_data->viewed_array_buffer();
|
src_data_span = SET_ERROR_VALUE_IF_ERROR(get_offset_span<u8 const>(*src_data, /* src_offset= */ 0), GL_INVALID_OPERATION);
|
||||||
auto const& byte_buffer = viewed_array_buffer->buffer();
|
|
||||||
src_data_ptr = byte_buffer.data() + src_data->byte_offset();
|
|
||||||
buffer_size = src_data->byte_length();
|
|
||||||
}
|
}
|
||||||
glTexImage3DRobustANGLE(target, level, internalformat, width, height, depth, border, format, type, buffer_size, src_data_ptr);
|
|
||||||
|
glTexImage3DRobustANGLE(target, level, internalformat, width, height, depth, border, format, type, src_data_span.size(), src_data_span.data());
|
||||||
}
|
}
|
||||||
|
|
||||||
void WebGL2RenderingContextImpl::tex_image3d(WebIDL::UnsignedLong target, WebIDL::Long level, WebIDL::Long internalformat, WebIDL::Long width, WebIDL::Long height, WebIDL::Long depth, WebIDL::Long border, WebIDL::UnsignedLong format, WebIDL::UnsignedLong type, GC::Root<WebIDL::ArrayBufferView> src_data, WebIDL::UnsignedLongLong src_offset)
|
void WebGL2RenderingContextImpl::tex_image3d(WebIDL::UnsignedLong target, WebIDL::Long level, WebIDL::Long internalformat, WebIDL::Long width, WebIDL::Long height, WebIDL::Long depth, WebIDL::Long border, WebIDL::UnsignedLong format, WebIDL::UnsignedLong type, GC::Root<WebIDL::ArrayBufferView> src_data, WebIDL::UnsignedLongLong src_offset)
|
||||||
{
|
{
|
||||||
m_context->make_current();
|
m_context->make_current();
|
||||||
|
|
||||||
void const* src_data_ptr = nullptr;
|
ReadonlyBytes src_data_span;
|
||||||
size_t buffer_size = 0;
|
|
||||||
if (src_data) {
|
if (src_data) {
|
||||||
auto const& viewed_array_buffer = src_data->viewed_array_buffer();
|
src_data_span = SET_ERROR_VALUE_IF_ERROR(get_offset_span<u8 const>(*src_data, src_offset), GL_INVALID_OPERATION);
|
||||||
auto const& byte_buffer = viewed_array_buffer->buffer();
|
|
||||||
src_data_ptr = byte_buffer.data() + src_offset;
|
|
||||||
buffer_size = src_data->byte_length();
|
|
||||||
}
|
}
|
||||||
glTexImage3DRobustANGLE(target, level, internalformat, width, height, depth, border, format, type, buffer_size, src_data_ptr);
|
|
||||||
|
glTexImage3DRobustANGLE(target, level, internalformat, width, height, depth, border, format, type, src_data_span.size(), src_data_span.data());
|
||||||
}
|
}
|
||||||
|
|
||||||
void WebGL2RenderingContextImpl::tex_sub_image3d(WebIDL::UnsignedLong target, WebIDL::Long level, WebIDL::Long xoffset, WebIDL::Long yoffset, WebIDL::Long zoffset, WebIDL::Long width, WebIDL::Long height, WebIDL::Long depth, WebIDL::UnsignedLong format, WebIDL::UnsignedLong type, GC::Root<WebIDL::ArrayBufferView> src_data, WebIDL::UnsignedLongLong src_offset)
|
void WebGL2RenderingContextImpl::tex_sub_image3d(WebIDL::UnsignedLong target, WebIDL::Long level, WebIDL::Long xoffset, WebIDL::Long yoffset, WebIDL::Long zoffset, WebIDL::Long width, WebIDL::Long height, WebIDL::Long depth, WebIDL::UnsignedLong format, WebIDL::UnsignedLong type, GC::Root<WebIDL::ArrayBufferView> src_data, WebIDL::UnsignedLongLong src_offset)
|
||||||
{
|
{
|
||||||
m_context->make_current();
|
m_context->make_current();
|
||||||
|
|
||||||
void const* pixels_ptr = nullptr;
|
ReadonlyBytes src_data_span;
|
||||||
size_t buffer_size = 0;
|
|
||||||
if (src_data) {
|
if (src_data) {
|
||||||
auto const& viewed_array_buffer = src_data->viewed_array_buffer();
|
src_data_span = SET_ERROR_VALUE_IF_ERROR(get_offset_span<u8 const>(*src_data, src_offset), GL_INVALID_OPERATION);
|
||||||
auto const& byte_buffer = viewed_array_buffer->buffer();
|
|
||||||
pixels_ptr = byte_buffer.data() + src_offset;
|
|
||||||
buffer_size = src_data->byte_length();
|
|
||||||
}
|
}
|
||||||
glTexSubImage3DRobustANGLE(target, level, xoffset, yoffset, zoffset, width, height, depth, format, type, buffer_size, pixels_ptr);
|
|
||||||
|
glTexSubImage3DRobustANGLE(target, level, xoffset, yoffset, zoffset, width, height, depth, format, type, src_data_span.size(), src_data_span.data());
|
||||||
}
|
}
|
||||||
|
|
||||||
void WebGL2RenderingContextImpl::uniform1ui(GC::Root<WebGLUniformLocation> location, WebIDL::UnsignedLong v0)
|
void WebGL2RenderingContextImpl::uniform1ui(GC::Root<WebGLUniformLocation> location, WebIDL::UnsignedLong v0)
|
||||||
|
|
@ -229,18 +230,18 @@ void WebGL2RenderingContextImpl::clear_bufferfv(WebIDL::UnsignedLong buffer, Web
|
||||||
m_context->make_current();
|
m_context->make_current();
|
||||||
m_context->notify_content_will_change();
|
m_context->notify_content_will_change();
|
||||||
|
|
||||||
auto span = span_from_float32_list(values);
|
auto span = SET_ERROR_VALUE_IF_ERROR(span_from_float32_list(values, src_offset), GL_INVALID_VALUE);
|
||||||
|
|
||||||
switch (buffer) {
|
switch (buffer) {
|
||||||
case GL_COLOR:
|
case GL_COLOR:
|
||||||
if (src_offset + 4 > span.size()) {
|
if (span.size() < 4) {
|
||||||
set_error(GL_INVALID_VALUE);
|
set_error(GL_INVALID_VALUE);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case GL_DEPTH:
|
case GL_DEPTH:
|
||||||
case GL_STENCIL:
|
case GL_STENCIL:
|
||||||
if (src_offset + 1 > span.size()) {
|
if (span.size() < 1) {
|
||||||
set_error(GL_INVALID_VALUE);
|
set_error(GL_INVALID_VALUE);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
@ -251,7 +252,6 @@ void WebGL2RenderingContextImpl::clear_bufferfv(WebIDL::UnsignedLong buffer, Web
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
span = span.slice(src_offset);
|
|
||||||
glClearBufferfv(buffer, drawbuffer, span.data());
|
glClearBufferfv(buffer, drawbuffer, span.data());
|
||||||
needs_to_present();
|
needs_to_present();
|
||||||
}
|
}
|
||||||
|
|
@ -261,19 +261,18 @@ void WebGL2RenderingContextImpl::clear_bufferiv(WebIDL::UnsignedLong buffer, Web
|
||||||
m_context->make_current();
|
m_context->make_current();
|
||||||
m_context->notify_content_will_change();
|
m_context->notify_content_will_change();
|
||||||
|
|
||||||
auto span = span_from_int32_list(values);
|
auto span = SET_ERROR_VALUE_IF_ERROR(span_from_int32_list(values, src_offset), GL_INVALID_VALUE);
|
||||||
auto count = span.size();
|
|
||||||
|
|
||||||
switch (buffer) {
|
switch (buffer) {
|
||||||
case GL_COLOR:
|
case GL_COLOR:
|
||||||
if (src_offset + 4 > count) {
|
if (span.size() < 4) {
|
||||||
set_error(GL_INVALID_VALUE);
|
set_error(GL_INVALID_VALUE);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case GL_DEPTH:
|
case GL_DEPTH:
|
||||||
case GL_STENCIL:
|
case GL_STENCIL:
|
||||||
if (src_offset + 1 > count) {
|
if (span.size() < 1) {
|
||||||
set_error(GL_INVALID_VALUE);
|
set_error(GL_INVALID_VALUE);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
@ -284,7 +283,6 @@ void WebGL2RenderingContextImpl::clear_bufferiv(WebIDL::UnsignedLong buffer, Web
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
span = span.slice(src_offset);
|
|
||||||
glClearBufferiv(buffer, drawbuffer, span.data());
|
glClearBufferiv(buffer, drawbuffer, span.data());
|
||||||
needs_to_present();
|
needs_to_present();
|
||||||
}
|
}
|
||||||
|
|
@ -294,17 +292,17 @@ void WebGL2RenderingContextImpl::clear_bufferuiv(WebIDL::UnsignedLong buffer, We
|
||||||
m_context->make_current();
|
m_context->make_current();
|
||||||
m_context->notify_content_will_change();
|
m_context->notify_content_will_change();
|
||||||
|
|
||||||
auto span = span_from_uint32_list(values);
|
auto span = SET_ERROR_VALUE_IF_ERROR(span_from_uint32_list(values, src_offset), GL_INVALID_VALUE);
|
||||||
switch (buffer) {
|
switch (buffer) {
|
||||||
case GL_COLOR:
|
case GL_COLOR:
|
||||||
if (src_offset + 4 > span.size()) {
|
if (span.size() < 4) {
|
||||||
set_error(GL_INVALID_VALUE);
|
set_error(GL_INVALID_VALUE);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case GL_DEPTH:
|
case GL_DEPTH:
|
||||||
case GL_STENCIL:
|
case GL_STENCIL:
|
||||||
if (src_offset + 1 > span.size()) {
|
if (span.size() < 1) {
|
||||||
set_error(GL_INVALID_VALUE);
|
set_error(GL_INVALID_VALUE);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
@ -315,7 +313,6 @@ void WebGL2RenderingContextImpl::clear_bufferuiv(WebIDL::UnsignedLong buffer, We
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
span = span.slice(src_offset);
|
|
||||||
glClearBufferuiv(buffer, drawbuffer, span.data());
|
glClearBufferuiv(buffer, drawbuffer, span.data());
|
||||||
needs_to_present();
|
needs_to_present();
|
||||||
}
|
}
|
||||||
|
|
@ -729,119 +726,44 @@ void WebGL2RenderingContextImpl::buffer_data(WebIDL::UnsignedLong target, GC::Ro
|
||||||
{
|
{
|
||||||
m_context->make_current();
|
m_context->make_current();
|
||||||
|
|
||||||
void const* ptr = nullptr;
|
auto data = MUST(get_offset_span<u8 const>(*src_data, /* src_offset= */ 0));
|
||||||
size_t byte_size = 0;
|
glBufferData(target, data.size(), data.data(), usage);
|
||||||
if (src_data->is_typed_array_base()) {
|
|
||||||
auto& typed_array_base = static_cast<JS::TypedArrayBase&>(*src_data->raw_object());
|
|
||||||
ptr = typed_array_base.viewed_array_buffer()->buffer().data() + typed_array_base.byte_offset();
|
|
||||||
byte_size = src_data->byte_length();
|
|
||||||
} else if (src_data->is_data_view()) {
|
|
||||||
auto& data_view = static_cast<JS::DataView&>(*src_data->raw_object());
|
|
||||||
ptr = data_view.viewed_array_buffer()->buffer().data();
|
|
||||||
byte_size = data_view.viewed_array_buffer()->byte_length();
|
|
||||||
} else if (src_data->is_array_buffer()) {
|
|
||||||
auto& array_buffer = static_cast<JS::ArrayBuffer&>(*src_data->raw_object());
|
|
||||||
ptr = array_buffer.buffer().data();
|
|
||||||
byte_size = array_buffer.byte_length();
|
|
||||||
} else {
|
|
||||||
VERIFY_NOT_REACHED();
|
|
||||||
}
|
|
||||||
glBufferData(target, byte_size, ptr, usage);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void WebGL2RenderingContextImpl::buffer_sub_data(WebIDL::UnsignedLong target, WebIDL::LongLong dst_byte_offset, GC::Root<WebIDL::BufferSource> src_data)
|
void WebGL2RenderingContextImpl::buffer_sub_data(WebIDL::UnsignedLong target, WebIDL::LongLong dst_byte_offset, GC::Root<WebIDL::BufferSource> src_data)
|
||||||
{
|
{
|
||||||
m_context->make_current();
|
m_context->make_current();
|
||||||
|
|
||||||
void const* ptr = nullptr;
|
auto data = MUST(get_offset_span<u8 const>(*src_data, /* src_offset= */ 0));
|
||||||
size_t byte_size = 0;
|
glBufferSubData(target, dst_byte_offset, data.size(), data.data());
|
||||||
if (src_data->is_typed_array_base()) {
|
|
||||||
auto& typed_array_base = static_cast<JS::TypedArrayBase&>(*src_data->raw_object());
|
|
||||||
ptr = typed_array_base.viewed_array_buffer()->buffer().data() + typed_array_base.byte_offset();
|
|
||||||
byte_size = src_data->byte_length();
|
|
||||||
} else if (src_data->is_data_view()) {
|
|
||||||
auto& data_view = static_cast<JS::DataView&>(*src_data->raw_object());
|
|
||||||
ptr = data_view.viewed_array_buffer()->buffer().data();
|
|
||||||
byte_size = data_view.viewed_array_buffer()->byte_length();
|
|
||||||
} else if (src_data->is_array_buffer()) {
|
|
||||||
auto& array_buffer = static_cast<JS::ArrayBuffer&>(*src_data->raw_object());
|
|
||||||
ptr = array_buffer.buffer().data();
|
|
||||||
byte_size = array_buffer.byte_length();
|
|
||||||
} else {
|
|
||||||
VERIFY_NOT_REACHED();
|
|
||||||
}
|
|
||||||
glBufferSubData(target, dst_byte_offset, byte_size, ptr);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void WebGL2RenderingContextImpl::buffer_data(WebIDL::UnsignedLong target, GC::Root<WebIDL::ArrayBufferView> src_data, WebIDL::UnsignedLong usage, WebIDL::UnsignedLongLong src_offset, WebIDL::UnsignedLong length)
|
void WebGL2RenderingContextImpl::buffer_data(WebIDL::UnsignedLong target, GC::Root<WebIDL::ArrayBufferView> src_data, WebIDL::UnsignedLong usage, WebIDL::UnsignedLongLong src_offset, WebIDL::UnsignedLong length)
|
||||||
{
|
{
|
||||||
m_context->make_current();
|
m_context->make_current();
|
||||||
|
|
||||||
VERIFY(src_data);
|
auto span = SET_ERROR_VALUE_IF_ERROR(get_offset_span<u8 const>(*src_data, src_offset, length), GL_INVALID_VALUE);
|
||||||
auto const& viewed_array_buffer = src_data->viewed_array_buffer();
|
glBufferData(target, span.size(), span.data(), usage);
|
||||||
auto const& byte_buffer = viewed_array_buffer->buffer();
|
|
||||||
auto src_data_length = src_data->byte_length();
|
|
||||||
auto src_data_element_size = src_data->element_size();
|
|
||||||
u8 const* buffer_ptr = byte_buffer.data();
|
|
||||||
|
|
||||||
u64 copy_length = length == 0 ? src_data_length - src_offset : length;
|
|
||||||
copy_length *= src_data_element_size;
|
|
||||||
|
|
||||||
if (src_offset > src_data_length) {
|
|
||||||
set_error(GL_INVALID_VALUE);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (src_offset + copy_length > src_data_length) {
|
|
||||||
set_error(GL_INVALID_VALUE);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
buffer_ptr += src_offset * src_data_element_size;
|
|
||||||
glBufferData(target, copy_length, buffer_ptr, usage);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void WebGL2RenderingContextImpl::buffer_sub_data(WebIDL::UnsignedLong target, WebIDL::LongLong dst_byte_offset, GC::Root<WebIDL::ArrayBufferView> src_data, WebIDL::UnsignedLongLong src_offset, WebIDL::UnsignedLong length)
|
void WebGL2RenderingContextImpl::buffer_sub_data(WebIDL::UnsignedLong target, WebIDL::LongLong dst_byte_offset, GC::Root<WebIDL::ArrayBufferView> src_data, WebIDL::UnsignedLongLong src_offset, WebIDL::UnsignedLong length)
|
||||||
{
|
{
|
||||||
m_context->make_current();
|
m_context->make_current();
|
||||||
|
|
||||||
VERIFY(src_data);
|
auto span = SET_ERROR_VALUE_IF_ERROR(get_offset_span<u8 const>(*src_data, src_offset, length), GL_INVALID_VALUE);
|
||||||
auto const& viewed_array_buffer = src_data->viewed_array_buffer();
|
glBufferSubData(target, dst_byte_offset, span.size(), span.data());
|
||||||
auto const& byte_buffer = viewed_array_buffer->buffer();
|
|
||||||
auto src_data_length = src_data->byte_length();
|
|
||||||
auto src_data_element_size = src_data->element_size();
|
|
||||||
u8 const* buffer_ptr = byte_buffer.data();
|
|
||||||
|
|
||||||
u64 copy_length = length == 0 ? src_data_length - src_offset : length;
|
|
||||||
copy_length *= src_data_element_size;
|
|
||||||
|
|
||||||
if (src_offset > src_data_length) {
|
|
||||||
set_error(GL_INVALID_VALUE);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (src_offset + copy_length > src_data_length) {
|
|
||||||
set_error(GL_INVALID_VALUE);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
buffer_ptr += src_offset * src_data_element_size;
|
|
||||||
glBufferSubData(target, dst_byte_offset, copy_length, buffer_ptr);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void WebGL2RenderingContextImpl::tex_image2d(WebIDL::UnsignedLong target, WebIDL::Long level, WebIDL::Long internalformat, WebIDL::Long width, WebIDL::Long height, WebIDL::Long border, WebIDL::UnsignedLong format, WebIDL::UnsignedLong type, GC::Root<WebIDL::ArrayBufferView> pixels)
|
void WebGL2RenderingContextImpl::tex_image2d(WebIDL::UnsignedLong target, WebIDL::Long level, WebIDL::Long internalformat, WebIDL::Long width, WebIDL::Long height, WebIDL::Long border, WebIDL::UnsignedLong format, WebIDL::UnsignedLong type, GC::Root<WebIDL::ArrayBufferView> pixels)
|
||||||
{
|
{
|
||||||
m_context->make_current();
|
m_context->make_current();
|
||||||
|
|
||||||
void const* pixels_ptr = nullptr;
|
ReadonlyBytes pixels_span;
|
||||||
size_t buffer_size = 0;
|
|
||||||
if (pixels) {
|
if (pixels) {
|
||||||
auto const& viewed_array_buffer = pixels->viewed_array_buffer();
|
pixels_span = SET_ERROR_VALUE_IF_ERROR(get_offset_span<u8 const>(*pixels, /* src_offset= */ 0), GL_INVALID_OPERATION);
|
||||||
auto const& byte_buffer = viewed_array_buffer->buffer();
|
|
||||||
pixels_ptr = byte_buffer.data() + pixels->byte_offset();
|
|
||||||
buffer_size = pixels->byte_length();
|
|
||||||
}
|
}
|
||||||
glTexImage2DRobustANGLE(target, level, internalformat, width, height, border, format, type, buffer_size, pixels_ptr);
|
|
||||||
|
glTexImage2DRobustANGLE(target, level, internalformat, width, height, border, format, type, pixels_span.size(), pixels_span.data());
|
||||||
}
|
}
|
||||||
|
|
||||||
void WebGL2RenderingContextImpl::tex_image2d(WebIDL::UnsignedLong target, WebIDL::Long level, WebIDL::Long internalformat, WebIDL::UnsignedLong format, WebIDL::UnsignedLong type, TexImageSource source)
|
void WebGL2RenderingContextImpl::tex_image2d(WebIDL::UnsignedLong target, WebIDL::Long level, WebIDL::Long internalformat, WebIDL::UnsignedLong format, WebIDL::UnsignedLong type, TexImageSource source)
|
||||||
|
|
@ -859,15 +781,12 @@ void WebGL2RenderingContextImpl::tex_sub_image2d(WebIDL::UnsignedLong target, We
|
||||||
{
|
{
|
||||||
m_context->make_current();
|
m_context->make_current();
|
||||||
|
|
||||||
void const* pixels_ptr = nullptr;
|
ReadonlyBytes pixels_span;
|
||||||
size_t buffer_size = 0;
|
|
||||||
if (pixels) {
|
if (pixels) {
|
||||||
auto const& viewed_array_buffer = pixels->viewed_array_buffer();
|
pixels_span = SET_ERROR_VALUE_IF_ERROR(get_offset_span<u8 const>(*pixels, /* src_offset= */ 0), GL_INVALID_OPERATION);
|
||||||
auto const& byte_buffer = viewed_array_buffer->buffer();
|
|
||||||
pixels_ptr = byte_buffer.data() + pixels->byte_offset();
|
|
||||||
buffer_size = pixels->byte_length();
|
|
||||||
}
|
}
|
||||||
glTexSubImage2DRobustANGLE(target, level, xoffset, yoffset, width, height, format, type, buffer_size, pixels_ptr);
|
|
||||||
|
glTexSubImage2DRobustANGLE(target, level, xoffset, yoffset, width, height, format, type, pixels_span.size(), pixels_span.data());
|
||||||
}
|
}
|
||||||
|
|
||||||
void WebGL2RenderingContextImpl::tex_sub_image2d(WebIDL::UnsignedLong target, WebIDL::Long level, WebIDL::Long xoffset, WebIDL::Long yoffset, WebIDL::UnsignedLong format, WebIDL::UnsignedLong type, TexImageSource source)
|
void WebGL2RenderingContextImpl::tex_sub_image2d(WebIDL::UnsignedLong target, WebIDL::Long level, WebIDL::Long xoffset, WebIDL::Long yoffset, WebIDL::UnsignedLong format, WebIDL::UnsignedLong type, TexImageSource source)
|
||||||
|
|
@ -897,15 +816,12 @@ void WebGL2RenderingContextImpl::tex_image2d(WebIDL::UnsignedLong target, WebIDL
|
||||||
{
|
{
|
||||||
m_context->make_current();
|
m_context->make_current();
|
||||||
|
|
||||||
void const* pixels_ptr = nullptr;
|
ReadonlyBytes pixels_span;
|
||||||
size_t buffer_size = 0;
|
|
||||||
if (src_data) {
|
if (src_data) {
|
||||||
auto const& viewed_array_buffer = src_data->viewed_array_buffer();
|
pixels_span = SET_ERROR_VALUE_IF_ERROR(get_offset_span<u8 const>(*src_data, src_offset), GL_INVALID_OPERATION);
|
||||||
auto const& byte_buffer = viewed_array_buffer->buffer();
|
|
||||||
pixels_ptr = byte_buffer.data() + src_offset;
|
|
||||||
buffer_size = src_data->byte_length();
|
|
||||||
}
|
}
|
||||||
glTexImage2DRobustANGLE(target, level, internalformat, width, height, border, format, type, buffer_size, pixels_ptr);
|
|
||||||
|
glTexImage2DRobustANGLE(target, level, internalformat, width, height, border, format, type, pixels_span.size(), pixels_span.data());
|
||||||
}
|
}
|
||||||
|
|
||||||
void WebGL2RenderingContextImpl::tex_sub_image2d(WebIDL::UnsignedLong target, WebIDL::Long level, WebIDL::Long xoffset, WebIDL::Long yoffset, WebIDL::Long width, WebIDL::Long height, WebIDL::UnsignedLong format, WebIDL::UnsignedLong type, TexImageSource source)
|
void WebGL2RenderingContextImpl::tex_sub_image2d(WebIDL::UnsignedLong target, WebIDL::Long level, WebIDL::Long xoffset, WebIDL::Long yoffset, WebIDL::Long width, WebIDL::Long height, WebIDL::UnsignedLong format, WebIDL::UnsignedLong type, TexImageSource source)
|
||||||
|
|
@ -924,63 +840,28 @@ void WebGL2RenderingContextImpl::tex_sub_image2d(WebIDL::UnsignedLong target, We
|
||||||
{
|
{
|
||||||
m_context->make_current();
|
m_context->make_current();
|
||||||
|
|
||||||
void const* pixels_ptr = nullptr;
|
ReadonlyBytes pixels_span;
|
||||||
size_t buffer_size = 0;
|
|
||||||
if (src_data) {
|
if (src_data) {
|
||||||
auto const& viewed_array_buffer = src_data->viewed_array_buffer();
|
pixels_span = SET_ERROR_VALUE_IF_ERROR(get_offset_span<u8 const>(*src_data, src_offset), GL_INVALID_OPERATION);
|
||||||
auto const& byte_buffer = viewed_array_buffer->buffer();
|
|
||||||
pixels_ptr = byte_buffer.data() + src_data->byte_offset() + src_offset;
|
|
||||||
buffer_size = src_data->byte_length();
|
|
||||||
}
|
}
|
||||||
glTexSubImage2DRobustANGLE(target, level, xoffset, yoffset, width, height, format, type, buffer_size, pixels_ptr);
|
|
||||||
|
glTexSubImage2DRobustANGLE(target, level, xoffset, yoffset, width, height, format, type, pixels_span.size(), pixels_span.data());
|
||||||
}
|
}
|
||||||
|
|
||||||
void WebGL2RenderingContextImpl::compressed_tex_image2d(WebIDL::UnsignedLong target, WebIDL::Long level, WebIDL::UnsignedLong internalformat, WebIDL::Long width, WebIDL::Long height, WebIDL::Long border, GC::Root<WebIDL::ArrayBufferView> src_data, WebIDL::UnsignedLongLong src_offset, WebIDL::UnsignedLong src_length_override)
|
void WebGL2RenderingContextImpl::compressed_tex_image2d(WebIDL::UnsignedLong target, WebIDL::Long level, WebIDL::UnsignedLong internalformat, WebIDL::Long width, WebIDL::Long height, WebIDL::Long border, GC::Root<WebIDL::ArrayBufferView> src_data, WebIDL::UnsignedLongLong src_offset, WebIDL::UnsignedLong src_length_override)
|
||||||
{
|
{
|
||||||
m_context->make_current();
|
m_context->make_current();
|
||||||
|
|
||||||
u8 const* pixels_ptr = src_data->viewed_array_buffer()->buffer().data();
|
auto pixels = SET_ERROR_VALUE_IF_ERROR(get_offset_span<u8 const>(*src_data, src_offset, src_length_override), GL_INVALID_VALUE);
|
||||||
size_t count = src_data->byte_length();
|
glCompressedTexImage2DRobustANGLE(target, level, internalformat, width, height, border, pixels.size(), pixels.size(), pixels.data());
|
||||||
auto src_data_element_size = src_data->element_size();
|
|
||||||
|
|
||||||
if ((src_offset * src_data_element_size) + src_length_override > count) {
|
|
||||||
set_error(GL_INVALID_VALUE);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
pixels_ptr += src_data->byte_offset();
|
|
||||||
pixels_ptr += src_offset * src_data_element_size;
|
|
||||||
if (src_length_override == 0) {
|
|
||||||
count -= src_offset;
|
|
||||||
} else {
|
|
||||||
count = src_length_override;
|
|
||||||
}
|
|
||||||
|
|
||||||
glCompressedTexImage2DRobustANGLE(target, level, internalformat, width, height, border, count, src_data->byte_length(), pixels_ptr);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void WebGL2RenderingContextImpl::compressed_tex_sub_image2d(WebIDL::UnsignedLong target, WebIDL::Long level, WebIDL::Long xoffset, WebIDL::Long yoffset, WebIDL::Long width, WebIDL::Long height, WebIDL::UnsignedLong format, GC::Root<WebIDL::ArrayBufferView> src_data, WebIDL::UnsignedLongLong src_offset, WebIDL::UnsignedLong src_length_override)
|
void WebGL2RenderingContextImpl::compressed_tex_sub_image2d(WebIDL::UnsignedLong target, WebIDL::Long level, WebIDL::Long xoffset, WebIDL::Long yoffset, WebIDL::Long width, WebIDL::Long height, WebIDL::UnsignedLong format, GC::Root<WebIDL::ArrayBufferView> src_data, WebIDL::UnsignedLongLong src_offset, WebIDL::UnsignedLong src_length_override)
|
||||||
{
|
{
|
||||||
m_context->make_current();
|
m_context->make_current();
|
||||||
|
|
||||||
u8 const* pixels_ptr = src_data->viewed_array_buffer()->buffer().data();
|
auto pixels = SET_ERROR_VALUE_IF_ERROR(get_offset_span<u8 const>(*src_data, src_offset, src_length_override), GL_INVALID_VALUE);
|
||||||
size_t count = src_data->byte_length();
|
glCompressedTexSubImage2DRobustANGLE(target, level, xoffset, yoffset, width, height, format, pixels.size(), pixels.size(), pixels.data());
|
||||||
auto src_data_element_size = src_data->element_size();
|
|
||||||
|
|
||||||
if ((src_offset * src_data_element_size) + src_length_override > count) {
|
|
||||||
set_error(GL_INVALID_VALUE);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
pixels_ptr += src_data->byte_offset();
|
|
||||||
pixels_ptr += src_offset * src_data_element_size;
|
|
||||||
if (src_length_override == 0) {
|
|
||||||
count -= src_offset;
|
|
||||||
} else {
|
|
||||||
count = src_length_override;
|
|
||||||
}
|
|
||||||
|
|
||||||
glCompressedTexSubImage2DRobustANGLE(target, level, xoffset, yoffset, width, height, format, count, src_data->byte_length(), pixels_ptr);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void WebGL2RenderingContextImpl::uniform1fv(GC::Root<WebGLUniformLocation> location, Float32List values, WebIDL::UnsignedLongLong src_offset, WebIDL::UnsignedLong src_length)
|
void WebGL2RenderingContextImpl::uniform1fv(GC::Root<WebGLUniformLocation> location, Float32List values, WebIDL::UnsignedLongLong src_offset, WebIDL::UnsignedLong src_length)
|
||||||
|
|
@ -990,189 +871,109 @@ void WebGL2RenderingContextImpl::uniform1fv(GC::Root<WebGLUniformLocation> locat
|
||||||
if (!location)
|
if (!location)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
auto span = span_from_float32_list(values);
|
auto span = SET_ERROR_VALUE_IF_ERROR(span_from_float32_list(values, src_offset, src_length), GL_INVALID_VALUE);
|
||||||
auto count = span.size();
|
glUniform1fv(location->handle(), span.size(), span.data());
|
||||||
if (src_offset + src_length > count) {
|
|
||||||
set_error(GL_INVALID_VALUE);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
span = span.slice(src_offset);
|
|
||||||
if (src_length == 0) {
|
|
||||||
count -= src_offset;
|
|
||||||
} else {
|
|
||||||
count = src_length;
|
|
||||||
}
|
|
||||||
|
|
||||||
glUniform1fv(location->handle(), count, span.data());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void WebGL2RenderingContextImpl::uniform2fv(GC::Root<WebGLUniformLocation> location, Float32List v, WebIDL::UnsignedLongLong src_offset, WebIDL::UnsignedLong src_length)
|
void WebGL2RenderingContextImpl::uniform2fv(GC::Root<WebGLUniformLocation> location, Float32List values, WebIDL::UnsignedLongLong src_offset, WebIDL::UnsignedLong src_length)
|
||||||
{
|
{
|
||||||
m_context->make_current();
|
m_context->make_current();
|
||||||
|
|
||||||
if (!location)
|
if (!location)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
auto span = span_from_float32_list(v);
|
auto span = SET_ERROR_VALUE_IF_ERROR(span_from_float32_list(values, src_offset, src_length), GL_INVALID_VALUE);
|
||||||
auto count = span.size();
|
if (span.size() % 2 != 0) [[unlikely]] {
|
||||||
if (src_offset + src_length > span.size()) {
|
|
||||||
set_error(GL_INVALID_VALUE);
|
set_error(GL_INVALID_VALUE);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
glUniform2fv(location->handle(), span.size() / 2, span.data());
|
||||||
span = span.slice(src_offset);
|
|
||||||
if (src_length == 0) {
|
|
||||||
count -= src_offset;
|
|
||||||
} else {
|
|
||||||
count = src_length;
|
|
||||||
}
|
|
||||||
|
|
||||||
glUniform2fv(location->handle(), count / 2, span.data());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void WebGL2RenderingContextImpl::uniform3fv(GC::Root<WebGLUniformLocation> location, Float32List v, WebIDL::UnsignedLongLong src_offset, WebIDL::UnsignedLong src_length)
|
void WebGL2RenderingContextImpl::uniform3fv(GC::Root<WebGLUniformLocation> location, Float32List values, WebIDL::UnsignedLongLong src_offset, WebIDL::UnsignedLong src_length)
|
||||||
{
|
{
|
||||||
m_context->make_current();
|
m_context->make_current();
|
||||||
|
|
||||||
if (!location)
|
if (!location)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
auto span = span_from_float32_list(v);
|
auto span = SET_ERROR_VALUE_IF_ERROR(span_from_float32_list(values, src_offset, src_length), GL_INVALID_VALUE);
|
||||||
auto count = span.size();
|
if (span.size() % 3 != 0) [[unlikely]] {
|
||||||
if (src_offset + src_length > count) {
|
|
||||||
set_error(GL_INVALID_VALUE);
|
set_error(GL_INVALID_VALUE);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
glUniform3fv(location->handle(), span.size() / 3, span.data());
|
||||||
span = span.slice(src_offset);
|
|
||||||
if (src_length == 0) {
|
|
||||||
count -= src_offset;
|
|
||||||
} else {
|
|
||||||
count = src_length;
|
|
||||||
}
|
|
||||||
|
|
||||||
glUniform3fv(location->handle(), count / 3, span.data());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void WebGL2RenderingContextImpl::uniform4fv(GC::Root<WebGLUniformLocation> location, Float32List v, WebIDL::UnsignedLongLong src_offset, WebIDL::UnsignedLong src_length)
|
void WebGL2RenderingContextImpl::uniform4fv(GC::Root<WebGLUniformLocation> location, Float32List values, WebIDL::UnsignedLongLong src_offset, WebIDL::UnsignedLong src_length)
|
||||||
{
|
{
|
||||||
m_context->make_current();
|
m_context->make_current();
|
||||||
|
|
||||||
if (!location)
|
if (!location)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
auto span = span_from_float32_list(v);
|
auto span = SET_ERROR_VALUE_IF_ERROR(span_from_float32_list(values, src_offset, src_length), GL_INVALID_VALUE);
|
||||||
auto count = span.size();
|
if (span.size() % 4 != 0) [[unlikely]] {
|
||||||
if (src_offset + src_length > count) {
|
|
||||||
set_error(GL_INVALID_VALUE);
|
set_error(GL_INVALID_VALUE);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
glUniform4fv(location->handle(), span.size() / 4, span.data());
|
||||||
span = span.slice(src_offset);
|
|
||||||
if (src_length == 0) {
|
|
||||||
count -= src_offset;
|
|
||||||
} else {
|
|
||||||
count = src_length;
|
|
||||||
}
|
|
||||||
|
|
||||||
glUniform4fv(location->handle(), count / 4, span.data());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void WebGL2RenderingContextImpl::uniform1iv(GC::Root<WebGLUniformLocation> location, Int32List v, WebIDL::UnsignedLongLong src_offset, WebIDL::UnsignedLong src_length)
|
void WebGL2RenderingContextImpl::uniform1iv(GC::Root<WebGLUniformLocation> location, Int32List values, WebIDL::UnsignedLongLong src_offset, WebIDL::UnsignedLong src_length)
|
||||||
{
|
{
|
||||||
m_context->make_current();
|
m_context->make_current();
|
||||||
|
|
||||||
if (!location)
|
if (!location)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
auto span = span_from_int32_list(v);
|
auto span = SET_ERROR_VALUE_IF_ERROR(span_from_int32_list(values, src_offset, src_length), GL_INVALID_VALUE);
|
||||||
auto count = span.size();
|
glUniform1iv(location->handle(), span.size(), span.data());
|
||||||
if (src_offset + src_length > count) {
|
|
||||||
set_error(GL_INVALID_VALUE);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
span = span.slice(src_offset);
|
|
||||||
if (src_length == 0) {
|
|
||||||
count -= src_offset;
|
|
||||||
} else {
|
|
||||||
count = src_length;
|
|
||||||
}
|
|
||||||
|
|
||||||
glUniform1iv(location->handle(), count / 1, span.data());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void WebGL2RenderingContextImpl::uniform2iv(GC::Root<WebGLUniformLocation> location, Int32List v, WebIDL::UnsignedLongLong src_offset, WebIDL::UnsignedLong src_length)
|
void WebGL2RenderingContextImpl::uniform2iv(GC::Root<WebGLUniformLocation> location, Int32List values, WebIDL::UnsignedLongLong src_offset, WebIDL::UnsignedLong src_length)
|
||||||
{
|
{
|
||||||
m_context->make_current();
|
m_context->make_current();
|
||||||
|
|
||||||
if (!location)
|
if (!location)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
auto span = span_from_int32_list(v);
|
auto span = SET_ERROR_VALUE_IF_ERROR(span_from_int32_list(values, src_offset, src_length), GL_INVALID_VALUE);
|
||||||
auto count = span.size();
|
if (span.size() % 2 != 0) [[unlikely]] {
|
||||||
if (src_offset + src_length > count) {
|
|
||||||
set_error(GL_INVALID_VALUE);
|
set_error(GL_INVALID_VALUE);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
glUniform2iv(location->handle(), span.size() / 2, span.data());
|
||||||
span = span.slice(src_offset);
|
|
||||||
if (src_length == 0) {
|
|
||||||
count -= src_offset;
|
|
||||||
} else {
|
|
||||||
count = src_length;
|
|
||||||
}
|
|
||||||
|
|
||||||
glUniform2iv(location->handle(), count / 2, span.data());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void WebGL2RenderingContextImpl::uniform3iv(GC::Root<WebGLUniformLocation> location, Int32List v, WebIDL::UnsignedLongLong src_offset, WebIDL::UnsignedLong src_length)
|
void WebGL2RenderingContextImpl::uniform3iv(GC::Root<WebGLUniformLocation> location, Int32List values, WebIDL::UnsignedLongLong src_offset, WebIDL::UnsignedLong src_length)
|
||||||
{
|
{
|
||||||
m_context->make_current();
|
m_context->make_current();
|
||||||
|
|
||||||
if (!location)
|
if (!location)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
auto span = span_from_int32_list(v);
|
auto span = SET_ERROR_VALUE_IF_ERROR(span_from_int32_list(values, src_offset, src_length), GL_INVALID_VALUE);
|
||||||
auto count = span.size();
|
if (span.size() % 3 != 0) [[unlikely]] {
|
||||||
if (src_offset + src_length > count) {
|
|
||||||
set_error(GL_INVALID_VALUE);
|
set_error(GL_INVALID_VALUE);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
glUniform3iv(location->handle(), span.size() / 3, span.data());
|
||||||
span = span.slice(src_offset);
|
|
||||||
if (src_length == 0) {
|
|
||||||
count -= src_offset;
|
|
||||||
} else {
|
|
||||||
count = src_length;
|
|
||||||
}
|
|
||||||
|
|
||||||
glUniform3iv(location->handle(), count / 3, span.data());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void WebGL2RenderingContextImpl::uniform4iv(GC::Root<WebGLUniformLocation> location, Int32List v, WebIDL::UnsignedLongLong src_offset, WebIDL::UnsignedLong src_length)
|
void WebGL2RenderingContextImpl::uniform4iv(GC::Root<WebGLUniformLocation> location, Int32List values, WebIDL::UnsignedLongLong src_offset, WebIDL::UnsignedLong src_length)
|
||||||
{
|
{
|
||||||
m_context->make_current();
|
m_context->make_current();
|
||||||
|
|
||||||
if (!location)
|
if (!location)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
auto span = span_from_int32_list(v);
|
auto span = SET_ERROR_VALUE_IF_ERROR(span_from_int32_list(values, src_offset, src_length), GL_INVALID_VALUE);
|
||||||
auto count = span.size();
|
if (span.size() % 4 != 0) [[unlikely]] {
|
||||||
if (src_offset + src_length > count) {
|
|
||||||
set_error(GL_INVALID_VALUE);
|
set_error(GL_INVALID_VALUE);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
glUniform4iv(location->handle(), span.size() / 4, span.data());
|
||||||
span = span.slice(src_offset);
|
|
||||||
if (src_length == 0) {
|
|
||||||
count -= src_offset;
|
|
||||||
} else {
|
|
||||||
count = src_length;
|
|
||||||
}
|
|
||||||
|
|
||||||
glUniform4iv(location->handle(), count / 4, span.data());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void WebGL2RenderingContextImpl::uniform_matrix2fv(GC::Root<WebGLUniformLocation> location, bool transpose, Float32List data, WebIDL::UnsignedLongLong src_offset, WebIDL::UnsignedLong src_length)
|
void WebGL2RenderingContextImpl::uniform_matrix2fv(GC::Root<WebGLUniformLocation> location, bool transpose, Float32List data, WebIDL::UnsignedLongLong src_offset, WebIDL::UnsignedLong src_length)
|
||||||
|
|
@ -1182,23 +983,13 @@ void WebGL2RenderingContextImpl::uniform_matrix2fv(GC::Root<WebGLUniformLocation
|
||||||
if (!location)
|
if (!location)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
auto matrix_size = 2 * 2;
|
constexpr auto matrix_size = 2 * 2;
|
||||||
auto span = span_from_float32_list(data);
|
auto span = SET_ERROR_VALUE_IF_ERROR(span_from_float32_list(data, src_offset, src_length), GL_INVALID_VALUE);
|
||||||
auto count = span.size() / matrix_size;
|
if (span.size() % matrix_size != 0) [[unlikely]] {
|
||||||
|
|
||||||
if (src_offset + src_length > (count * matrix_size)) {
|
|
||||||
set_error(GL_INVALID_VALUE);
|
set_error(GL_INVALID_VALUE);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
glUniformMatrix2fv(location->handle(), span.size() / matrix_size, transpose, span.data());
|
||||||
span = span.slice(src_offset);
|
|
||||||
if (src_length == 0) {
|
|
||||||
count -= src_offset;
|
|
||||||
} else {
|
|
||||||
count = src_length;
|
|
||||||
}
|
|
||||||
|
|
||||||
glUniformMatrix2fv(location->handle(), count, transpose, span.data());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void WebGL2RenderingContextImpl::uniform_matrix3fv(GC::Root<WebGLUniformLocation> location, bool transpose, Float32List data, WebIDL::UnsignedLongLong src_offset, WebIDL::UnsignedLong src_length)
|
void WebGL2RenderingContextImpl::uniform_matrix3fv(GC::Root<WebGLUniformLocation> location, bool transpose, Float32List data, WebIDL::UnsignedLongLong src_offset, WebIDL::UnsignedLong src_length)
|
||||||
|
|
@ -1208,23 +999,13 @@ void WebGL2RenderingContextImpl::uniform_matrix3fv(GC::Root<WebGLUniformLocation
|
||||||
if (!location)
|
if (!location)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
auto matrix_size = 3 * 3;
|
constexpr auto matrix_size = 3 * 3;
|
||||||
auto span = span_from_float32_list(data);
|
auto span = SET_ERROR_VALUE_IF_ERROR(span_from_float32_list(data, src_offset, src_length), GL_INVALID_VALUE);
|
||||||
auto count = span.size() / matrix_size;
|
if (span.size() % matrix_size != 0) [[unlikely]] {
|
||||||
|
|
||||||
if (src_offset + src_length > (count * matrix_size)) {
|
|
||||||
set_error(GL_INVALID_VALUE);
|
set_error(GL_INVALID_VALUE);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
glUniformMatrix3fv(location->handle(), span.size() / matrix_size, transpose, span.data());
|
||||||
span = span.slice(src_offset);
|
|
||||||
if (src_length == 0) {
|
|
||||||
count -= src_offset;
|
|
||||||
} else {
|
|
||||||
count = src_length;
|
|
||||||
}
|
|
||||||
|
|
||||||
glUniformMatrix3fv(location->handle(), count, transpose, span.data());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void WebGL2RenderingContextImpl::uniform_matrix4fv(GC::Root<WebGLUniformLocation> location, bool transpose, Float32List data, WebIDL::UnsignedLongLong src_offset, WebIDL::UnsignedLong src_length)
|
void WebGL2RenderingContextImpl::uniform_matrix4fv(GC::Root<WebGLUniformLocation> location, bool transpose, Float32List data, WebIDL::UnsignedLongLong src_offset, WebIDL::UnsignedLong src_length)
|
||||||
|
|
@ -1234,23 +1015,13 @@ void WebGL2RenderingContextImpl::uniform_matrix4fv(GC::Root<WebGLUniformLocation
|
||||||
if (!location)
|
if (!location)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
auto matrix_size = 4 * 4;
|
constexpr auto matrix_size = 4 * 4;
|
||||||
auto span = span_from_float32_list(data);
|
auto span = SET_ERROR_VALUE_IF_ERROR(span_from_float32_list(data, src_offset, src_length), GL_INVALID_VALUE);
|
||||||
auto count = span.size() / matrix_size;
|
if (span.size() % matrix_size != 0) [[unlikely]] {
|
||||||
|
|
||||||
if (src_offset + src_length > (count * matrix_size)) {
|
|
||||||
set_error(GL_INVALID_VALUE);
|
set_error(GL_INVALID_VALUE);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
glUniformMatrix4fv(location->handle(), span.size() / matrix_size, transpose, span.data());
|
||||||
span = span.slice(src_offset);
|
|
||||||
if (src_length == 0) {
|
|
||||||
count -= src_offset;
|
|
||||||
} else {
|
|
||||||
count = src_length;
|
|
||||||
}
|
|
||||||
|
|
||||||
glUniformMatrix4fv(location->handle(), count, transpose, span.data());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void WebGL2RenderingContextImpl::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)
|
void WebGL2RenderingContextImpl::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)
|
||||||
|
|
@ -1261,8 +1032,8 @@ void WebGL2RenderingContextImpl::read_pixels(WebIDL::Long x, WebIDL::Long y, Web
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
void* ptr = pixels->viewed_array_buffer()->buffer().data() + pixels->byte_offset();
|
auto span = MUST(get_offset_span<u8>(*pixels, /* src_offset= */ 0));
|
||||||
glReadPixelsRobustANGLE(x, y, width, height, format, type, pixels->byte_length(), nullptr, nullptr, nullptr, ptr);
|
glReadPixelsRobustANGLE(x, y, width, height, format, type, span.size(), nullptr, nullptr, nullptr, span.data());
|
||||||
}
|
}
|
||||||
|
|
||||||
void WebGL2RenderingContextImpl::active_texture(WebIDL::UnsignedLong texture)
|
void WebGL2RenderingContextImpl::active_texture(WebIDL::UnsignedLong texture)
|
||||||
|
|
@ -3095,7 +2866,7 @@ void WebGL2RenderingContextImpl::vertex_attrib1fv(WebIDL::UnsignedLong index, Fl
|
||||||
{
|
{
|
||||||
m_context->make_current();
|
m_context->make_current();
|
||||||
|
|
||||||
auto span = span_from_float32_list(values);
|
auto span = MUST(span_from_float32_list(values, /* src_offset= */ 0));
|
||||||
if (span.size() < 1) {
|
if (span.size() < 1) {
|
||||||
set_error(GL_INVALID_VALUE);
|
set_error(GL_INVALID_VALUE);
|
||||||
return;
|
return;
|
||||||
|
|
@ -3107,7 +2878,7 @@ void WebGL2RenderingContextImpl::vertex_attrib2fv(WebIDL::UnsignedLong index, Fl
|
||||||
{
|
{
|
||||||
m_context->make_current();
|
m_context->make_current();
|
||||||
|
|
||||||
auto span = span_from_float32_list(values);
|
auto span = MUST(span_from_float32_list(values, /* src_offset= */ 0));
|
||||||
if (span.size() < 2) {
|
if (span.size() < 2) {
|
||||||
set_error(GL_INVALID_VALUE);
|
set_error(GL_INVALID_VALUE);
|
||||||
return;
|
return;
|
||||||
|
|
@ -3119,7 +2890,7 @@ void WebGL2RenderingContextImpl::vertex_attrib3fv(WebIDL::UnsignedLong index, Fl
|
||||||
{
|
{
|
||||||
m_context->make_current();
|
m_context->make_current();
|
||||||
|
|
||||||
auto span = span_from_float32_list(values);
|
auto span = MUST(span_from_float32_list(values, /* src_offset= */ 0));
|
||||||
if (span.size() < 3) {
|
if (span.size() < 3) {
|
||||||
set_error(GL_INVALID_VALUE);
|
set_error(GL_INVALID_VALUE);
|
||||||
return;
|
return;
|
||||||
|
|
@ -3131,7 +2902,7 @@ void WebGL2RenderingContextImpl::vertex_attrib4fv(WebIDL::UnsignedLong index, Fl
|
||||||
{
|
{
|
||||||
m_context->make_current();
|
m_context->make_current();
|
||||||
|
|
||||||
auto span = span_from_float32_list(values);
|
auto span = MUST(span_from_float32_list(values, /* src_offset= */ 0));
|
||||||
if (span.size() < 4) {
|
if (span.size() < 4) {
|
||||||
set_error(GL_INVALID_VALUE);
|
set_error(GL_INVALID_VALUE);
|
||||||
return;
|
return;
|
||||||
|
|
|
||||||
|
|
@ -6,8 +6,10 @@
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include <LibJS/Runtime/DataView.h>
|
||||||
#include <LibJS/Runtime/TypedArray.h>
|
#include <LibJS/Runtime/TypedArray.h>
|
||||||
#include <LibWeb/Forward.h>
|
#include <LibWeb/Forward.h>
|
||||||
|
#include <LibWeb/WebIDL/Buffers.h>
|
||||||
#include <LibWeb/WebIDL/Types.h>
|
#include <LibWeb/WebIDL/Types.h>
|
||||||
|
|
||||||
namespace Web::WebGL {
|
namespace Web::WebGL {
|
||||||
|
|
@ -28,25 +30,76 @@ public:
|
||||||
virtual OpenGLContext& context() = 0;
|
virtual OpenGLContext& context() = 0;
|
||||||
virtual bool ext_texture_filter_anisotropic_extension_enabled() const = 0;
|
virtual bool ext_texture_filter_anisotropic_extension_enabled() const = 0;
|
||||||
|
|
||||||
static Span<float> span_from_float32_list(Float32List& float32_list)
|
template<typename T>
|
||||||
|
static ErrorOr<Span<T>> get_offset_span(Span<T> src_span, WebIDL::UnsignedLongLong src_offset, WebIDL::UnsignedLong src_length_override = 0)
|
||||||
{
|
{
|
||||||
if (float32_list.has<Vector<float>>())
|
Checked<WebIDL::UnsignedLongLong> length = src_offset;
|
||||||
return float32_list.get<Vector<float>>();
|
length += src_length_override;
|
||||||
return float32_list.get<GC::Root<JS::Float32Array>>()->data();
|
if (length.has_overflow() || length.value_unchecked() > src_span.size()) [[unlikely]]
|
||||||
|
return Error::from_errno(EINVAL);
|
||||||
|
|
||||||
|
if (src_length_override == 0)
|
||||||
|
return src_span.slice(src_offset, src_span.size() - src_offset);
|
||||||
|
|
||||||
|
return src_span.slice(src_offset, src_length_override);
|
||||||
}
|
}
|
||||||
|
|
||||||
static Span<int> span_from_int32_list(Int32List& int32_list)
|
template<typename T>
|
||||||
|
static ErrorOr<Span<T>> get_offset_span(GC::Ref<WebIDL::BufferableObjectBase> src_data, WebIDL::UnsignedLongLong src_offset, WebIDL::UnsignedLong src_length_override = 0)
|
||||||
{
|
{
|
||||||
if (int32_list.has<Vector<int>>())
|
auto buffer_size = src_data->byte_length();
|
||||||
return int32_list.get<Vector<int>>();
|
if (buffer_size % sizeof(T) != 0) [[unlikely]]
|
||||||
return int32_list.get<GC::Root<JS::Int32Array>>()->data();
|
return Error::from_errno(EINVAL);
|
||||||
|
|
||||||
|
auto raw_object = src_data->raw_object();
|
||||||
|
|
||||||
|
if (auto* array_buffer = as_if<JS::ArrayBuffer>(*raw_object)) {
|
||||||
|
return TRY(get_offset_span(array_buffer->buffer().span(), src_offset, src_length_override)).reinterpret<T>();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (auto* data_view = as_if<JS::DataView>(*raw_object)) {
|
||||||
|
return TRY(get_offset_span(data_view->viewed_array_buffer()->buffer().span(), src_offset, src_length_override)).reinterpret<T>();
|
||||||
|
}
|
||||||
|
|
||||||
|
// NOTE: This has to be done because src_offset is the number of elements to offset by, not the number of bytes.
|
||||||
|
#define __JS_ENUMERATE(ClassName, snake_name, PrototypeName, ConstructorName, Type) \
|
||||||
|
if (auto* typed_array = as_if<JS::ClassName>(*raw_object)) { \
|
||||||
|
return TRY(get_offset_span(typed_array->data(), src_offset, src_length_override)).reinterpret<T>(); \
|
||||||
|
}
|
||||||
|
JS_ENUMERATE_TYPED_ARRAYS
|
||||||
|
#undef __JS_ENUMERATE
|
||||||
|
|
||||||
|
VERIFY_NOT_REACHED();
|
||||||
}
|
}
|
||||||
|
|
||||||
static Span<u32> span_from_uint32_list(Uint32List& int32_list)
|
static ErrorOr<Span<float>> span_from_float32_list(Float32List& float32_list, WebIDL::UnsignedLongLong src_offset, WebIDL::UnsignedLong src_length_override = 0)
|
||||||
{
|
{
|
||||||
if (int32_list.has<Vector<u32>>())
|
if (float32_list.has<Vector<float>>()) {
|
||||||
return int32_list.get<Vector<u32>>();
|
auto& vector = float32_list.get<Vector<float>>();
|
||||||
return int32_list.get<GC::Root<JS::Uint32Array>>()->data();
|
return get_offset_span(vector.span(), src_offset, src_length_override);
|
||||||
|
}
|
||||||
|
auto& buffer = float32_list.get<GC::Root<JS::Float32Array>>();
|
||||||
|
return get_offset_span(buffer->data(), src_offset, src_length_override);
|
||||||
|
}
|
||||||
|
|
||||||
|
static ErrorOr<Span<int>> span_from_int32_list(Int32List& int32_list, WebIDL::UnsignedLongLong src_offset, WebIDL::UnsignedLong src_length_override = 0)
|
||||||
|
{
|
||||||
|
if (int32_list.has<Vector<int>>()) {
|
||||||
|
auto& vector = int32_list.get<Vector<int>>();
|
||||||
|
return get_offset_span(vector.span(), src_offset, src_length_override);
|
||||||
|
}
|
||||||
|
auto& buffer = int32_list.get<GC::Root<JS::Int32Array>>();
|
||||||
|
return get_offset_span(buffer->data(), src_offset, src_length_override);
|
||||||
|
}
|
||||||
|
|
||||||
|
static ErrorOr<Span<u32>> span_from_uint32_list(Uint32List& uint32_list, WebIDL::UnsignedLongLong src_offset, WebIDL::UnsignedLong src_length_override = 0)
|
||||||
|
{
|
||||||
|
if (uint32_list.has<Vector<u32>>()) {
|
||||||
|
auto& vector = uint32_list.get<Vector<u32>>();
|
||||||
|
return get_offset_span(vector.span(), src_offset, src_length_override);
|
||||||
|
}
|
||||||
|
auto& buffer = uint32_list.get<GC::Root<JS::Uint32Array>>();
|
||||||
|
return get_offset_span(buffer->data(), src_offset, src_length_override);
|
||||||
}
|
}
|
||||||
|
|
||||||
struct ConvertedTexture {
|
struct ConvertedTexture {
|
||||||
|
|
|
||||||
|
|
@ -59,66 +59,32 @@ void WebGLRenderingContextImpl::buffer_data(WebIDL::UnsignedLong target, GC::Roo
|
||||||
{
|
{
|
||||||
m_context->make_current();
|
m_context->make_current();
|
||||||
|
|
||||||
void const* ptr = nullptr;
|
auto span = MUST(get_offset_span<u8 const>(*data, /* src_offset= */ 0));
|
||||||
size_t byte_size = 0;
|
glBufferData(target, span.size(), span.data(), usage);
|
||||||
if (data->is_typed_array_base()) {
|
|
||||||
auto& typed_array_base = static_cast<JS::TypedArrayBase&>(*data->raw_object());
|
|
||||||
ptr = typed_array_base.viewed_array_buffer()->buffer().data() + typed_array_base.byte_offset();
|
|
||||||
byte_size = data->byte_length();
|
|
||||||
} else if (data->is_data_view()) {
|
|
||||||
auto& data_view = static_cast<JS::DataView&>(*data->raw_object());
|
|
||||||
ptr = data_view.viewed_array_buffer()->buffer().data();
|
|
||||||
byte_size = data_view.viewed_array_buffer()->byte_length();
|
|
||||||
} else if (data->is_array_buffer()) {
|
|
||||||
auto& array_buffer = static_cast<JS::ArrayBuffer&>(*data->raw_object());
|
|
||||||
ptr = array_buffer.buffer().data();
|
|
||||||
byte_size = array_buffer.byte_length();
|
|
||||||
} else {
|
|
||||||
VERIFY_NOT_REACHED();
|
|
||||||
}
|
|
||||||
glBufferData(target, byte_size, ptr, usage);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void WebGLRenderingContextImpl::buffer_sub_data(WebIDL::UnsignedLong target, WebIDL::LongLong offset, GC::Root<WebIDL::BufferSource> data)
|
void WebGLRenderingContextImpl::buffer_sub_data(WebIDL::UnsignedLong target, WebIDL::LongLong offset, GC::Root<WebIDL::BufferSource> data)
|
||||||
{
|
{
|
||||||
m_context->make_current();
|
m_context->make_current();
|
||||||
|
|
||||||
void const* ptr = nullptr;
|
auto span = MUST(get_offset_span<u8 const>(*data, /* src_offset= */ 0));
|
||||||
size_t byte_size = 0;
|
glBufferSubData(target, offset, span.size(), span.data());
|
||||||
if (data->is_typed_array_base()) {
|
|
||||||
auto& typed_array_base = static_cast<JS::TypedArrayBase&>(*data->raw_object());
|
|
||||||
ptr = typed_array_base.viewed_array_buffer()->buffer().data() + typed_array_base.byte_offset();
|
|
||||||
byte_size = data->byte_length();
|
|
||||||
} else if (data->is_data_view()) {
|
|
||||||
auto& data_view = static_cast<JS::DataView&>(*data->raw_object());
|
|
||||||
ptr = data_view.viewed_array_buffer()->buffer().data();
|
|
||||||
byte_size = data_view.viewed_array_buffer()->byte_length();
|
|
||||||
} else if (data->is_array_buffer()) {
|
|
||||||
auto& array_buffer = static_cast<JS::ArrayBuffer&>(*data->raw_object());
|
|
||||||
ptr = array_buffer.buffer().data();
|
|
||||||
byte_size = array_buffer.byte_length();
|
|
||||||
} else {
|
|
||||||
VERIFY_NOT_REACHED();
|
|
||||||
}
|
|
||||||
glBufferSubData(target, offset, byte_size, ptr);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void WebGLRenderingContextImpl::compressed_tex_image2d(WebIDL::UnsignedLong target, WebIDL::Long level, WebIDL::UnsignedLong internalformat, WebIDL::Long width, WebIDL::Long height, WebIDL::Long border, GC::Root<WebIDL::ArrayBufferView> data)
|
void WebGLRenderingContextImpl::compressed_tex_image2d(WebIDL::UnsignedLong target, WebIDL::Long level, WebIDL::UnsignedLong internalformat, WebIDL::Long width, WebIDL::Long height, WebIDL::Long border, GC::Root<WebIDL::ArrayBufferView> data)
|
||||||
{
|
{
|
||||||
m_context->make_current();
|
m_context->make_current();
|
||||||
|
|
||||||
void const* ptr = data->viewed_array_buffer()->buffer().data() + data->byte_offset();
|
auto span = MUST(get_offset_span<u8 const>(*data, /* src_offset= */ 0));
|
||||||
size_t byte_size = data->byte_length();
|
glCompressedTexImage2DRobustANGLE(target, level, internalformat, width, height, border, span.size(), span.size(), span.data());
|
||||||
glCompressedTexImage2DRobustANGLE(target, level, internalformat, width, height, border, byte_size, byte_size, ptr);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void WebGLRenderingContextImpl::compressed_tex_sub_image2d(WebIDL::UnsignedLong target, WebIDL::Long level, WebIDL::Long xoffset, WebIDL::Long yoffset, WebIDL::Long width, WebIDL::Long height, WebIDL::UnsignedLong format, GC::Root<WebIDL::ArrayBufferView> data)
|
void WebGLRenderingContextImpl::compressed_tex_sub_image2d(WebIDL::UnsignedLong target, WebIDL::Long level, WebIDL::Long xoffset, WebIDL::Long yoffset, WebIDL::Long width, WebIDL::Long height, WebIDL::UnsignedLong format, GC::Root<WebIDL::ArrayBufferView> data)
|
||||||
{
|
{
|
||||||
m_context->make_current();
|
m_context->make_current();
|
||||||
|
|
||||||
void const* ptr = data->viewed_array_buffer()->buffer().data() + data->byte_offset();
|
auto span = MUST(get_offset_span<u8 const>(*data, /* src_offset= */ 0));
|
||||||
size_t byte_size = data->byte_length();
|
glCompressedTexSubImage2DRobustANGLE(target, level, xoffset, yoffset, width, height, format, span.size(), span.size(), span.data());
|
||||||
glCompressedTexSubImage2DRobustANGLE(target, level, xoffset, yoffset, width, height, format, byte_size, byte_size, ptr);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void WebGLRenderingContextImpl::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)
|
void WebGLRenderingContextImpl::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)
|
||||||
|
|
@ -129,23 +95,16 @@ void WebGLRenderingContextImpl::read_pixels(WebIDL::Long x, WebIDL::Long y, WebI
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
void* ptr = pixels->viewed_array_buffer()->buffer().data() + pixels->byte_offset();
|
auto span = MUST(get_offset_span<u8>(*pixels, /* src_offset= */ 0));
|
||||||
glReadPixelsRobustANGLE(x, y, width, height, format, type, pixels->byte_length(), nullptr, nullptr, nullptr, ptr);
|
glReadPixelsRobustANGLE(x, y, width, height, format, type, span.size(), nullptr, nullptr, nullptr, span.data());
|
||||||
}
|
}
|
||||||
|
|
||||||
void WebGLRenderingContextImpl::tex_image2d(WebIDL::UnsignedLong target, WebIDL::Long level, WebIDL::Long internalformat, WebIDL::Long width, WebIDL::Long height, WebIDL::Long border, WebIDL::UnsignedLong format, WebIDL::UnsignedLong type, GC::Root<WebIDL::ArrayBufferView> pixels)
|
void WebGLRenderingContextImpl::tex_image2d(WebIDL::UnsignedLong target, WebIDL::Long level, WebIDL::Long internalformat, WebIDL::Long width, WebIDL::Long height, WebIDL::Long border, WebIDL::UnsignedLong format, WebIDL::UnsignedLong type, GC::Root<WebIDL::ArrayBufferView> pixels)
|
||||||
{
|
{
|
||||||
m_context->make_current();
|
m_context->make_current();
|
||||||
|
|
||||||
void const* pixels_ptr = nullptr;
|
auto span = MUST(get_offset_span<u8>(*pixels, /* src_offset= */ 0));
|
||||||
size_t buffer_size = 0;
|
glTexImage2DRobustANGLE(target, level, internalformat, width, height, border, format, type, span.size(), span.data());
|
||||||
if (pixels) {
|
|
||||||
auto const& viewed_array_buffer = pixels->viewed_array_buffer();
|
|
||||||
auto const& byte_buffer = viewed_array_buffer->buffer();
|
|
||||||
pixels_ptr = byte_buffer.data() + pixels->byte_offset();
|
|
||||||
buffer_size = pixels->byte_length();
|
|
||||||
}
|
|
||||||
glTexImage2DRobustANGLE(target, level, internalformat, width, height, border, format, type, buffer_size, pixels_ptr);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void WebGLRenderingContextImpl::tex_image2d(WebIDL::UnsignedLong target, WebIDL::Long level, WebIDL::Long internalformat, WebIDL::UnsignedLong format, WebIDL::UnsignedLong type, TexImageSource source)
|
void WebGLRenderingContextImpl::tex_image2d(WebIDL::UnsignedLong target, WebIDL::Long level, WebIDL::Long internalformat, WebIDL::UnsignedLong format, WebIDL::UnsignedLong type, TexImageSource source)
|
||||||
|
|
@ -163,15 +122,8 @@ void WebGLRenderingContextImpl::tex_sub_image2d(WebIDL::UnsignedLong target, Web
|
||||||
{
|
{
|
||||||
m_context->make_current();
|
m_context->make_current();
|
||||||
|
|
||||||
void const* pixels_ptr = nullptr;
|
auto span = MUST(get_offset_span<u8>(*pixels, /* src_offset= */ 0));
|
||||||
size_t buffer_size = 0;
|
glTexSubImage2DRobustANGLE(target, level, xoffset, yoffset, width, height, format, type, span.size(), span.data());
|
||||||
if (pixels) {
|
|
||||||
auto const& viewed_array_buffer = pixels->viewed_array_buffer();
|
|
||||||
auto const& byte_buffer = viewed_array_buffer->buffer();
|
|
||||||
pixels_ptr = byte_buffer.data() + pixels->byte_offset();
|
|
||||||
buffer_size = pixels->byte_length();
|
|
||||||
}
|
|
||||||
glTexSubImage2DRobustANGLE(target, level, xoffset, yoffset, width, height, format, type, buffer_size, pixels_ptr);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void WebGLRenderingContextImpl::tex_sub_image2d(WebIDL::UnsignedLong target, WebIDL::Long level, WebIDL::Long xoffset, WebIDL::Long yoffset, WebIDL::UnsignedLong format, WebIDL::UnsignedLong type, TexImageSource source)
|
void WebGLRenderingContextImpl::tex_sub_image2d(WebIDL::UnsignedLong target, WebIDL::Long level, WebIDL::Long xoffset, WebIDL::Long yoffset, WebIDL::UnsignedLong format, WebIDL::UnsignedLong type, TexImageSource source)
|
||||||
|
|
@ -192,7 +144,7 @@ void WebGLRenderingContextImpl::uniform1fv(GC::Root<WebGLUniformLocation> locati
|
||||||
|
|
||||||
if (!location)
|
if (!location)
|
||||||
return;
|
return;
|
||||||
auto span = span_from_float32_list(v);
|
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());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -202,7 +154,11 @@ void WebGLRenderingContextImpl::uniform2fv(GC::Root<WebGLUniformLocation> locati
|
||||||
|
|
||||||
if (!location)
|
if (!location)
|
||||||
return;
|
return;
|
||||||
auto span = span_from_float32_list(v);
|
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());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -212,7 +168,11 @@ void WebGLRenderingContextImpl::uniform3fv(GC::Root<WebGLUniformLocation> locati
|
||||||
|
|
||||||
if (!location)
|
if (!location)
|
||||||
return;
|
return;
|
||||||
auto span = span_from_float32_list(v);
|
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());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -222,7 +182,11 @@ void WebGLRenderingContextImpl::uniform4fv(GC::Root<WebGLUniformLocation> locati
|
||||||
|
|
||||||
if (!location)
|
if (!location)
|
||||||
return;
|
return;
|
||||||
auto span = span_from_float32_list(v);
|
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());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -232,8 +196,8 @@ void WebGLRenderingContextImpl::uniform1iv(GC::Root<WebGLUniformLocation> locati
|
||||||
|
|
||||||
if (!location)
|
if (!location)
|
||||||
return;
|
return;
|
||||||
auto span = span_from_int32_list(v);
|
auto span = MUST(span_from_int32_list(v, /* src_offset= */ 0));
|
||||||
glUniform1iv(location->handle(), span.size() / 1, span.data());
|
glUniform1iv(location->handle(), span.size(), span.data());
|
||||||
}
|
}
|
||||||
|
|
||||||
void WebGLRenderingContextImpl::uniform2iv(GC::Root<WebGLUniformLocation> location, Int32List v)
|
void WebGLRenderingContextImpl::uniform2iv(GC::Root<WebGLUniformLocation> location, Int32List v)
|
||||||
|
|
@ -242,7 +206,11 @@ void WebGLRenderingContextImpl::uniform2iv(GC::Root<WebGLUniformLocation> locati
|
||||||
|
|
||||||
if (!location)
|
if (!location)
|
||||||
return;
|
return;
|
||||||
auto span = span_from_int32_list(v);
|
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());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -252,7 +220,11 @@ void WebGLRenderingContextImpl::uniform3iv(GC::Root<WebGLUniformLocation> locati
|
||||||
|
|
||||||
if (!location)
|
if (!location)
|
||||||
return;
|
return;
|
||||||
auto span = span_from_int32_list(v);
|
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());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -262,7 +234,11 @@ void WebGLRenderingContextImpl::uniform4iv(GC::Root<WebGLUniformLocation> locati
|
||||||
|
|
||||||
if (!location)
|
if (!location)
|
||||||
return;
|
return;
|
||||||
auto span = span_from_int32_list(v);
|
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());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -272,8 +248,12 @@ void WebGLRenderingContextImpl::uniform_matrix2fv(GC::Root<WebGLUniformLocation>
|
||||||
|
|
||||||
if (!location)
|
if (!location)
|
||||||
return;
|
return;
|
||||||
auto matrix_size = 2 * 2;
|
constexpr auto matrix_size = 2 * 2;
|
||||||
auto span = span_from_float32_list(value);
|
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());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -283,8 +263,12 @@ void WebGLRenderingContextImpl::uniform_matrix3fv(GC::Root<WebGLUniformLocation>
|
||||||
|
|
||||||
if (!location)
|
if (!location)
|
||||||
return;
|
return;
|
||||||
auto matrix_size = 3 * 3;
|
constexpr auto matrix_size = 3 * 3;
|
||||||
auto span = span_from_float32_list(value);
|
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());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -294,8 +278,12 @@ void WebGLRenderingContextImpl::uniform_matrix4fv(GC::Root<WebGLUniformLocation>
|
||||||
|
|
||||||
if (!location)
|
if (!location)
|
||||||
return;
|
return;
|
||||||
auto matrix_size = 4 * 4;
|
constexpr auto matrix_size = 4 * 4;
|
||||||
auto span = span_from_float32_list(value);
|
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());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1954,7 +1942,7 @@ void WebGLRenderingContextImpl::vertex_attrib1fv(WebIDL::UnsignedLong index, Flo
|
||||||
{
|
{
|
||||||
m_context->make_current();
|
m_context->make_current();
|
||||||
|
|
||||||
auto span = span_from_float32_list(values);
|
auto span = MUST(span_from_float32_list(values, /* src_offset= */ 0));
|
||||||
if (span.size() < 1) {
|
if (span.size() < 1) {
|
||||||
set_error(GL_INVALID_VALUE);
|
set_error(GL_INVALID_VALUE);
|
||||||
return;
|
return;
|
||||||
|
|
@ -1966,7 +1954,7 @@ void WebGLRenderingContextImpl::vertex_attrib2fv(WebIDL::UnsignedLong index, Flo
|
||||||
{
|
{
|
||||||
m_context->make_current();
|
m_context->make_current();
|
||||||
|
|
||||||
auto span = span_from_float32_list(values);
|
auto span = MUST(span_from_float32_list(values, /* src_offset= */ 0));
|
||||||
if (span.size() < 2) {
|
if (span.size() < 2) {
|
||||||
set_error(GL_INVALID_VALUE);
|
set_error(GL_INVALID_VALUE);
|
||||||
return;
|
return;
|
||||||
|
|
@ -1978,7 +1966,7 @@ void WebGLRenderingContextImpl::vertex_attrib3fv(WebIDL::UnsignedLong index, Flo
|
||||||
{
|
{
|
||||||
m_context->make_current();
|
m_context->make_current();
|
||||||
|
|
||||||
auto span = span_from_float32_list(values);
|
auto span = MUST(span_from_float32_list(values, /* src_offset= */ 0));
|
||||||
if (span.size() < 3) {
|
if (span.size() < 3) {
|
||||||
set_error(GL_INVALID_VALUE);
|
set_error(GL_INVALID_VALUE);
|
||||||
return;
|
return;
|
||||||
|
|
@ -1990,7 +1978,7 @@ void WebGLRenderingContextImpl::vertex_attrib4fv(WebIDL::UnsignedLong index, Flo
|
||||||
{
|
{
|
||||||
m_context->make_current();
|
m_context->make_current();
|
||||||
|
|
||||||
auto span = span_from_float32_list(values);
|
auto span = MUST(span_from_float32_list(values, /* src_offset= */ 0));
|
||||||
if (span.size() < 4) {
|
if (span.size() < 4) {
|
||||||
set_error(GL_INVALID_VALUE);
|
set_error(GL_INVALID_VALUE);
|
||||||
return;
|
return;
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue
Block a user