@@ -31,57 +31,28 @@ extern "C" {
3131
3232namespace Web ::WebGL {
3333
34- static constexpr Optional<int > opengl_format_and_type_number_of_bytes (WebIDL::UnsignedLong format, WebIDL::UnsignedLong type)
35- {
36- switch (format) {
37- case GL_LUMINANCE:
38- case GL_ALPHA:
39- if (type != GL_UNSIGNED_BYTE)
40- return OptionalNone {};
41-
42- return 1 ;
43- case GL_LUMINANCE_ALPHA:
44- if (type != GL_UNSIGNED_BYTE)
45- return OptionalNone {};
46-
47- return 2 ;
48- case GL_RGB:
49- if (type != GL_UNSIGNED_BYTE && type != GL_UNSIGNED_SHORT_5_6_5)
50- return OptionalNone {};
51-
52- return type == GL_UNSIGNED_BYTE ? 3 : 2 ;
53- case GL_RGBA:
54- if (type != GL_UNSIGNED_BYTE && type != GL_UNSIGNED_SHORT_4_4_4_4 && type != GL_UNSIGNED_SHORT_5_5_5_1)
55- return OptionalNone {};
56-
57- return type == GL_UNSIGNED_BYTE ? 4 : 2 ;
58- default :
59- return OptionalNone {};
60- }
61- }
62-
63- static constexpr SkColorType opengl_format_and_type_to_skia_color_type (WebIDL::UnsignedLong format, WebIDL::UnsignedLong type)
34+ static constexpr Optional<Gfx::ExportFormat> determine_export_format (WebIDL::UnsignedLong format, WebIDL::UnsignedLong type)
6435{
6536 switch (format) {
6637 case GL_RGB:
6738 switch (type) {
6839 case GL_UNSIGNED_BYTE:
69- return SkColorType:: kRGB_888x_SkColorType ;
40+ return Gfx::ExportFormat::RGB888 ;
7041 case GL_UNSIGNED_SHORT_5_6_5:
71- return SkColorType:: kRGB_565_SkColorType ;
42+ return Gfx::ExportFormat::RGB565 ;
7243 default :
7344 break ;
7445 }
7546 break ;
7647 case GL_RGBA:
7748 switch (type) {
7849 case GL_UNSIGNED_BYTE:
79- return SkColorType:: kRGBA_8888_SkColorType ;
50+ return Gfx::ExportFormat::RGBA8888 ;
8051 case GL_UNSIGNED_SHORT_4_4_4_4:
8152 // FIXME: This is not exactly the same as RGBA.
82- return SkColorType:: kARGB_4444_SkColorType ;
53+ return Gfx::ExportFormat::RGBA4444 ;
8354 case GL_UNSIGNED_SHORT_5_5_5_1:
84- dbgln ( " WebGL FIXME: Support conversion to RGBA5551. " ) ;
55+ return Gfx::ExportFormat:: RGBA5551;
8556 break ;
8657 default :
8758 break ;
@@ -90,15 +61,15 @@ static constexpr SkColorType opengl_format_and_type_to_skia_color_type(WebIDL::U
9061 case GL_ALPHA:
9162 switch (type) {
9263 case GL_UNSIGNED_BYTE:
93- return SkColorType:: kAlpha_8_SkColorType ;
64+ return Gfx::ExportFormat::Alpha8 ;
9465 default :
9566 break ;
9667 }
9768 break ;
9869 case GL_LUMINANCE:
9970 switch (type) {
10071 case GL_UNSIGNED_BYTE:
101- return SkColorType:: kGray_8_SkColorType ;
72+ return Gfx::ExportFormat::Gray8 ;
10273 default :
10374 break ;
10475 }
@@ -108,10 +79,10 @@ static constexpr SkColorType opengl_format_and_type_to_skia_color_type(WebIDL::U
10879 }
10980
11081 dbgln (" WebGL: Unsupported format and type combination. format: 0x{:04x}, type: 0x{:04x}" , format, type);
111- return SkColorType:: kUnknown_SkColorType ;
82+ return {} ;
11283}
11384
114- Optional<WebGLRenderingContextBase::ConvertedTexture > WebGLRenderingContextBase::read_and_pixel_convert_texture_image_source (TexImageSource const & source, WebIDL::UnsignedLong format, WebIDL::UnsignedLong type, Optional<int > destination_width, Optional<int > destination_height)
85+ Optional<Gfx::BitmapExportResult > WebGLRenderingContextBase::read_and_pixel_convert_texture_image_source (TexImageSource const & source, WebIDL::UnsignedLong format, WebIDL::UnsignedLong type, Optional<int > destination_width, Optional<int > destination_height)
11586{
11687 // FIXME: If this function is called with an ImageData whose data attribute has been neutered,
11788 // an INVALID_VALUE error is generated.
@@ -147,53 +118,27 @@ Optional<WebGLRenderingContextBase::ConvertedTexture> WebGLRenderingContextBase:
147118 if (!bitmap)
148119 return OptionalNone {};
149120
150- int width = destination_width.value_or (bitmap->width ());
151- int height = destination_height.value_or (bitmap->height ());
152-
153- Checked<size_t > buffer_pitch = width;
154-
155- auto number_of_bytes = opengl_format_and_type_number_of_bytes (format, type);
156- if (!number_of_bytes.has_value ())
157- return OptionalNone {};
158-
159- buffer_pitch *= number_of_bytes.value ();
160-
161- if (buffer_pitch.has_overflow ())
121+ auto export_format = determine_export_format (format, type);
122+ if (!export_format.has_value ())
162123 return OptionalNone {};
163124
164- if (Checked<size_t >::multiplication_would_overflow (buffer_pitch.value (), height))
165- return OptionalNone {};
166-
167- auto buffer = MUST (ByteBuffer::create_zeroed (buffer_pitch.value () * height));
168-
169- if (width > 0 && height > 0 ) {
170- // FIXME: Respect unpackColorSpace
171- auto skia_format = opengl_format_and_type_to_skia_color_type (format, type);
172- auto color_space = SkColorSpace::MakeSRGB ();
173- auto image_info = SkImageInfo::Make (width, height, skia_format, m_unpack_premultiply_alpha ? SkAlphaType::kPremul_SkAlphaType : SkAlphaType::kUnpremul_SkAlphaType , color_space);
174- auto surface = SkSurfaces::WrapPixels (image_info, buffer.data (), buffer_pitch.value ());
175- VERIFY (surface);
176- auto surface_canvas = surface->getCanvas ();
177- auto dst_rect = Gfx::to_skia_rect (Gfx::Rect { 0 , 0 , width, height });
178-
125+ // FIXME: Respect unpackColorSpace
126+ auto export_flags = 0 ;
127+ if (m_unpack_flip_y && !source.has <GC::Root<HTML::ImageBitmap>>())
179128 // The first pixel transferred from the source to the WebGL implementation corresponds to the upper left corner of
180129 // the source. This behavior is modified by the UNPACK_FLIP_Y_WEBGL pixel storage parameter, except for ImageBitmap
181130 // arguments, as described in the abovementioned section.
182- if (m_unpack_flip_y && !source.has <GC::Root<HTML::ImageBitmap>>()) {
183- surface_canvas->translate (0 , dst_rect.height ());
184- surface_canvas->scale (1 , -1 );
185- }
131+ export_flags |= Gfx::ExportFlags::FlipY;
132+ if (m_unpack_premultiply_alpha)
133+ export_flags |= Gfx::ExportFlags::PremultiplyAlpha;
186134
187- surface_canvas->drawImageRect (bitmap->sk_image (), dst_rect, Gfx::to_skia_sampling_options (Gfx::ScalingMode::NearestNeighbor));
188- } else {
189- VERIFY (buffer.is_empty ());
135+ auto result = bitmap->export_to_byte_buffer (export_format.value (), export_flags, destination_width, destination_height);
136+ if (result.is_error ()) {
137+ dbgln (" Could not export bitmap: {}" , result.release_error ());
138+ return OptionalNone {};
190139 }
191140
192- return ConvertedTexture {
193- .buffer = move (buffer),
194- .width = width,
195- .height = height,
196- };
141+ return result.release_value ();
197142}
198143
199144// TODO: The glGetError spec allows for queueing errors which is something we should probably do, for now
0 commit comments