Sfoglia il codice sorgente

LibWeb/WebGL2: Implement bufferSubData with offset and length

Luke Wilde 6 mesi fa
parent
commit
f3da3c412d

+ 1 - 1
Libraries/LibWeb/WebGL/WebGL2RenderingContextOverloads.idl

@@ -11,7 +11,7 @@ interface mixin WebGL2RenderingContextOverloads {
     undefined bufferSubData(GLenum target, GLintptr dstByteOffset, BufferSource srcData);
     // WebGL2:
     undefined bufferData(GLenum target, [AllowShared] ArrayBufferView srcData, GLenum usage, unsigned long long srcOffset, optional GLuint length = 0);
-    [FIXME] undefined bufferSubData(GLenum target, GLintptr dstByteOffset, [AllowShared] ArrayBufferView srcData, unsigned long long srcOffset, optional GLuint length = 0);
+    undefined bufferSubData(GLenum target, GLintptr dstByteOffset, [AllowShared] ArrayBufferView srcData, unsigned long long srcOffset, optional GLuint length = 0);
 
     // WebGL1 legacy entrypoints:
     undefined texImage2D(GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, [AllowShared] ArrayBufferView? pixels);

+ 28 - 0
Meta/Lagom/Tools/CodeGenerators/LibWeb/GenerateWebGLRenderingContext.cpp

@@ -830,6 +830,34 @@ public:
             continue;
         }
 
+        if (webgl_version == 2 && function.name == "bufferSubData"sv && function.overload_index == 1) {
+            function_impl_generator.append(R"~~~(
+    VERIFY(src_data);
+    auto const& viewed_array_buffer = src_data->viewed_array_buffer();
+    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);
+)~~~");
+            continue;
+        }
+
         if (function.name == "readPixels"sv) {
             function_impl_generator.append(R"~~~(
     if (!pixels) {