diff --git a/gsk/gl/gskglcommandqueue.c b/gsk/gl/gskglcommandqueue.c index c22ae00680..3db15181a3 100644 --- a/gsk/gl/gskglcommandqueue.c +++ b/gsk/gl/gskglcommandqueue.c @@ -1435,6 +1435,8 @@ gsk_gl_command_queue_create_texture (GskGLCommandQueue *self, switch (format) { + case 0: + break; case GL_RGBA8: glTexImage2D (GL_TEXTURE_2D, 0, format, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL); break; @@ -1689,7 +1691,7 @@ gsk_gl_command_queue_upload_texture_chunks (GskGLCommandQueue *self, height = MIN (height, self->max_texture_size); } - texture_id = gsk_gl_command_queue_create_texture (self, width, height, GL_RGBA8); + texture_id = gsk_gl_command_queue_create_texture (self, width, height, 0); if (texture_id == -1) return texture_id; diff --git a/testsuite/gsk/compare/mipmap-generation-later.node b/testsuite/gsk/compare/mipmap-generation-later.node new file mode 100644 index 0000000000..2c20c93b11 --- /dev/null +++ b/testsuite/gsk/compare/mipmap-generation-later.node @@ -0,0 +1,13 @@ +texture-scale { + bounds: 0 0 10 10; + filter: nearest; + texture: "texture1" url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACgAAAAoCAYAAACM/rhtAAAAZklEQVRYhe3SoQ3AMBAEwXOUQtJ/\ +Ve7kAxJqtOTADrGOWa9dszN58tn/W7TXJNPwkdO+Uu7OTsWlTrv+gjZI2SBlg5QNUjZI2SBlg5QN\ +UjZI2SBlg5QNUjZI2SBlg5QNUjZI1Tf4AnlN8eRDOVeLAAAAAElFTkSuQmCC\ +"); +} +texture-scale { + bounds: 15 0 10 10; + filter: trilinear; + texture: "texture1"; +} diff --git a/testsuite/gsk/compare/mipmap-generation-later.png b/testsuite/gsk/compare/mipmap-generation-later.png new file mode 100644 index 0000000000..f8f3ff8b6d Binary files /dev/null and b/testsuite/gsk/compare/mipmap-generation-later.png differ diff --git a/testsuite/gsk/meson.build b/testsuite/gsk/meson.build index ca789f1c5a..125490fadf 100644 --- a/testsuite/gsk/meson.build +++ b/testsuite/gsk/meson.build @@ -85,6 +85,7 @@ compare_render_tests = [ 'mask-modes-in-opacity', 'mask-modes-with-alpha', 'mask-texture-color-alpha', + 'mipmap-generation-later', 'nested-rounded-clips', 'offscreen-pixel-alignment-nogl-nocairo', 'opacity_clip', diff --git a/testsuite/reftests/glarea-gl-only.c b/testsuite/reftests/glarea-gl-only.c new file mode 100644 index 0000000000..40510d3beb --- /dev/null +++ b/testsuite/reftests/glarea-gl-only.c @@ -0,0 +1,82 @@ +#include +#include + +/* A png for a red/yellow checkerboard */ +static const char image_data[] = { + 0211, 0120, 0116, 0107, 0015, 0012, 0032, 0012, 0000, 0000, 0000, 0015, 0111, 0110, 0104, 0122, + 0000, 0000, 0000, 0040, 0000, 0000, 0000, 0040, 0001, 0003, 0000, 0000, 0000, 0111, 0264, 0350, + 0267, 0000, 0000, 0000, 0006, 0120, 0114, 0124, 0105, 0377, 0000, 0000, 0377, 0340, 0000, 0241, + 0105, 0325, 0002, 0000, 0000, 0000, 0025, 0111, 0104, 0101, 0124, 0010, 0327, 0143, 0230, 0011, + 0004, 0014, 0151, 0100, 0000, 0041, 0300, 0334, 0101, 0044, 0006, 0000, 0355, 0275, 0077, 0301, + 0347, 0173, 0153, 0007, 0000, 0000, 0000, 0000, 0111, 0105, 0116, 0104, 0256, 0102, 0140, 0202 +}; + +G_MODULE_EXPORT gboolean +render_orange_glonly (GtkWidget *glarea, + GdkGLContext *context) +{ + GdkTexture *texture; + GdkTextureDownloader *downloader; + GBytes *bytes; + gsize stride, width, height; + GLuint tex_id, fb_id; + + gdk_gl_context_make_current (context); + + /* Clear to green, so that errors in the following code cause a problem */ + glClearColor (0.0, 1.0, 0.0, 1.0); + glClear (GL_COLOR_BUFFER_BIT); + + /* load the checkerboard image */ + bytes = g_bytes_new_static (image_data, G_N_ELEMENTS (image_data)); + texture = gdk_texture_new_from_bytes (bytes, NULL); + g_bytes_unref (bytes); + width = gdk_texture_get_width (texture); + height = gdk_texture_get_height (texture); + downloader = gdk_texture_downloader_new (texture); + /* Make sure we use a format that GLES does *NOT* support. + * And that must include extensions. + * But GL_EXT_texture_norm16 does support RGB16 as a source, which + * is why we also use mipmaps below. */ + gdk_texture_downloader_set_format (downloader, GDK_MEMORY_R16G16B16); + bytes = gdk_texture_downloader_download_bytes (downloader, &stride); + g_object_unref (texture); + gdk_texture_downloader_free (downloader); + + glGenTextures (1, &tex_id); + glActiveTexture (GL_TEXTURE0); + glBindTexture (GL_TEXTURE_2D, tex_id); + /* Now load the image in this ideally unsupported format. Maybe + * things fail already here. Usually they don't. */ + glTexImage2D (GL_TEXTURE_2D, 0, GL_RGB16, + width, height, + 0, GL_RGB, GL_UNSIGNED_SHORT, g_bytes_get_data (bytes, NULL)); + g_bytes_unref (bytes); + /* Generate mipmaps. GLES should give up now. + * GL should turn the checkerboard into orange mipmap levels though. + */ + glGenerateMipmap (GL_TEXTURE_2D); + + glGenFramebuffers (1, &fb_id); + glBindFramebuffer (GL_READ_FRAMEBUFFER, fb_id); + /* Bind mipmap level 2 for reading, so we rely on properly converted + * mipmaps. */ + glFramebufferTexture2D (GL_READ_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, tex_id, 2); + + /* On GLES, this should now fail due to incomplete framebuffer and + * leave us with the green contents we've drawn above. + * Or we are on GL, everything works perfectly, and we now get orange. */ + glBlitFramebuffer (0, 0, + width / 4, height / 4, + 0, 0, + gtk_widget_get_width (glarea) * gtk_widget_get_scale_factor (glarea), + gtk_widget_get_height (glarea) * gtk_widget_get_scale_factor (glarea), + GL_COLOR_BUFFER_BIT, + GL_LINEAR); + + glDeleteFramebuffers (1, &fb_id); + glDeleteTextures (1, &tex_id); + + return TRUE; +} + diff --git a/testsuite/reftests/glarea-gl-only.css b/testsuite/reftests/glarea-gl-only.css new file mode 100644 index 0000000000..def6494c8d --- /dev/null +++ b/testsuite/reftests/glarea-gl-only.css @@ -0,0 +1,6 @@ +.orange { + /* The color of the mipmap'ed image */ + background-color: #ff7000; + /* So the error label doesn't show */ + color: transparent; +} diff --git a/testsuite/reftests/glarea-gl-only.ref.ui b/testsuite/reftests/glarea-gl-only.ref.ui new file mode 100644 index 0000000000..5e547d4bbd --- /dev/null +++ b/testsuite/reftests/glarea-gl-only.ref.ui @@ -0,0 +1,11 @@ + + + + 32 + 32 + 0 + + + diff --git a/testsuite/reftests/glarea-gl-only.ui b/testsuite/reftests/glarea-gl-only.ui new file mode 100644 index 0000000000..af5250b5cf --- /dev/null +++ b/testsuite/reftests/glarea-gl-only.ui @@ -0,0 +1,17 @@ + + + + 32 + 32 + 0 + + + gl + + + + + + diff --git a/testsuite/reftests/meson.build b/testsuite/reftests/meson.build index 7aa0498387..9a3288daef 100644 --- a/testsuite/reftests/meson.build +++ b/testsuite/reftests/meson.build @@ -18,6 +18,7 @@ libreftest = library('reftest', sources: [ 'expand-expander.c', 'frame-inhibitor.c', + 'glarea-gl-only.c', 'letter-spacing.c', 'set-default-direction.c', 'statusbar-remove-all.c', @@ -308,6 +309,9 @@ testdata = [ 'font-sizes-names.css', 'font-sizes-names.ref.ui', 'font-sizes-names.ui', + 'glarea-gl-only.css', + 'glarea-gl-only.ref.ui', + 'glarea-gl-only.ui', 'gtk-image-effect-inherit.css', 'gtk-image-effect-inherit.ref.ui', 'gtk-image-effect-inherit.ui',