From f2686c5ad8b73db8f37cfb6c3dfa10771a62e34d Mon Sep 17 00:00:00 2001 From: Mitchell Stokes Date: Sat, 13 Apr 2019 14:48:07 -0700 Subject: [PATCH 1/6] glsl: Fix Shader::_error_flag not being set on compile errors (#622) --- panda/src/glstuff/glShaderContext_src.cxx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/panda/src/glstuff/glShaderContext_src.cxx b/panda/src/glstuff/glShaderContext_src.cxx index d61d75beb6..618b228754 100644 --- a/panda/src/glstuff/glShaderContext_src.cxx +++ b/panda/src/glstuff/glShaderContext_src.cxx @@ -3306,7 +3306,7 @@ glsl_compile_and_link() { } _glgsg->report_my_gl_errors(); - return true; + return valid; } #endif // OPENGLES_1 From 369dccbab95e0c250d89d3154b673ac1b93952b2 Mon Sep 17 00:00:00 2001 From: Mitchell Stokes Date: Mon, 13 May 2019 20:26:27 -0700 Subject: [PATCH 2/6] tests: Add tests around compiling GLSL and Cg shaders (#622) --- tests/display/cg_bad.sha | 21 ++++++++++++++ tests/display/cg_simple.sha | 21 ++++++++++++++ tests/display/glsl_bad.vert | 12 ++++++++ tests/display/glsl_include.vert | 7 +++++ tests/display/glsl_include_inputs.vert | 5 ++++ tests/display/glsl_simple.frag | 5 ++++ tests/display/glsl_simple.vert | 11 ++++++++ tests/display/test_cg_shader.py | 28 +++++++++++++++++++ tests/display/test_glsl_shader.py | 38 ++++++++++++++++++++++++++ 9 files changed, 148 insertions(+) create mode 100644 tests/display/cg_bad.sha create mode 100644 tests/display/cg_simple.sha create mode 100644 tests/display/glsl_bad.vert create mode 100644 tests/display/glsl_include.vert create mode 100644 tests/display/glsl_include_inputs.vert create mode 100644 tests/display/glsl_simple.frag create mode 100644 tests/display/glsl_simple.vert create mode 100644 tests/display/test_cg_shader.py diff --git a/tests/display/cg_bad.sha b/tests/display/cg_bad.sha new file mode 100644 index 0000000000..7f3a77eda4 --- /dev/null +++ b/tests/display/cg_bad.sha @@ -0,0 +1,21 @@ +//Cg +// + +void vshader(float4 vtx_position : POSITION, + float2 vtx_texcoord0 : TEXCOORD0, + uniform float4x4 mat_modelproj, + out float4 l_position : POSITION, + out float2 l_texcoord0 : TEXCOORD0) +{ + l_position = mul(mat_modelproj, vtx_position); + l_texcoord0 = vtx_texcoord0; +} + +void fshader(float2 l_texcoord0 : TEXCOORD0, + uniform sampler2D tex_0 : TEXUNIT0, + out float4 o_color : COLOR) +{ + float4 texColor = tex2D(tex_0, l_texcoord0); + does_not_exist = texColor * 2 * (texColor.w - 0.5); +} + diff --git a/tests/display/cg_simple.sha b/tests/display/cg_simple.sha new file mode 100644 index 0000000000..64e419fd0e --- /dev/null +++ b/tests/display/cg_simple.sha @@ -0,0 +1,21 @@ +//Cg +// + +void vshader(float4 vtx_position : POSITION, + float2 vtx_texcoord0 : TEXCOORD0, + uniform float4x4 mat_modelproj, + out float4 l_position : POSITION, + out float2 l_texcoord0 : TEXCOORD0) +{ + l_position = mul(mat_modelproj, vtx_position); + l_texcoord0 = vtx_texcoord0; +} + +void fshader(float2 l_texcoord0 : TEXCOORD0, + uniform sampler2D tex_0 : TEXUNIT0, + out float4 o_color : COLOR) +{ + float4 texColor = tex2D(tex_0, l_texcoord0); + o_color = texColor * 2 * (texColor.w - 0.5); +} + diff --git a/tests/display/glsl_bad.vert b/tests/display/glsl_bad.vert new file mode 100644 index 0000000000..8a324916ec --- /dev/null +++ b/tests/display/glsl_bad.vert @@ -0,0 +1,12 @@ +#version 130 + +// Uniform inputs +uniform mat4 p3d_ModelViewProjectionMatrix; + +// Vertex inputs +in vec4 p3d_Vertex; + +void main() { + gl_Position = p3d_ModelViewProjectionMatrix * p3d_Vertex; + does_not_exist = p3d_Vertex; +} diff --git a/tests/display/glsl_include.vert b/tests/display/glsl_include.vert new file mode 100644 index 0000000000..1826fdf677 --- /dev/null +++ b/tests/display/glsl_include.vert @@ -0,0 +1,7 @@ +#version 130 + +#pragma include "glsl_include_inputs.vert" + +void main() { + gl_Position = p3d_ModelViewProjectionMatrix * p3d_Vertex; +} diff --git a/tests/display/glsl_include_inputs.vert b/tests/display/glsl_include_inputs.vert new file mode 100644 index 0000000000..125078ce16 --- /dev/null +++ b/tests/display/glsl_include_inputs.vert @@ -0,0 +1,5 @@ +// Uniform inputs +uniform mat4 p3d_ModelViewProjectionMatrix; + +// Vertex inputs +in vec4 p3d_Vertex; diff --git a/tests/display/glsl_simple.frag b/tests/display/glsl_simple.frag new file mode 100644 index 0000000000..5f190e015c --- /dev/null +++ b/tests/display/glsl_simple.frag @@ -0,0 +1,5 @@ +#version 130 + +void main() { + gl_FragColor = vec4(0, 0, 0, 1); +} diff --git a/tests/display/glsl_simple.vert b/tests/display/glsl_simple.vert new file mode 100644 index 0000000000..ea3afd7498 --- /dev/null +++ b/tests/display/glsl_simple.vert @@ -0,0 +1,11 @@ +#version 130 + +// Uniform inputs +uniform mat4 p3d_ModelViewProjectionMatrix; + +// Vertex inputs +in vec4 p3d_Vertex; + +void main() { + gl_Position = p3d_ModelViewProjectionMatrix * p3d_Vertex; +} diff --git a/tests/display/test_cg_shader.py b/tests/display/test_cg_shader.py new file mode 100644 index 0000000000..8a6c4d7a74 --- /dev/null +++ b/tests/display/test_cg_shader.py @@ -0,0 +1,28 @@ +import os + +from panda3d import core + + +SHADERS_DIR = core.Filename.from_os_specific(os.path.dirname(__file__)) + + +def run_cg_compile_check(gsg, shader_path, expect_fail=False): + """Compile supplied Cg shader path and check for errors""" + shader = core.Shader.load(shader_path, core.Shader.SL_Cg) + # assert shader.is_prepared(gsg.prepared_objects) + if expect_fail: + assert shader is None + else: + assert shader is not None + + +def test_cg_compile_error(gsg): + """Test getting compile errors from bad Cg shaders""" + shader_path = core.Filename(SHADERS_DIR, 'cg_bad.sha') + run_cg_compile_check(gsg, shader_path, expect_fail=True) + + +def test_cg_from_file(gsg): + """Test compiling Cg shaders from files""" + shader_path = core.Filename(SHADERS_DIR, 'cg_simple.sha') + run_cg_compile_check(gsg, shader_path) diff --git a/tests/display/test_glsl_shader.py b/tests/display/test_glsl_shader.py index 8deadf40d9..cb7ab165d4 100644 --- a/tests/display/test_glsl_shader.py +++ b/tests/display/test_glsl_shader.py @@ -1,9 +1,13 @@ from panda3d import core +import os import struct import pytest from _pytest.outcomes import Failed +SHADERS_DIR = core.Filename.from_os_specific(os.path.dirname(__file__)) + + # This is the template for the compute shader that is used by run_glsl_test. # It defines an assert() macro that writes failures to a buffer, indexed by # line number. @@ -102,6 +106,19 @@ def run_glsl_test(gsg, body, preamble="", inputs={}, version=150, exts=set()): pytest.fail("{0} GLSL assertions triggered:\n{1}".format(count, formatted)) +def run_glsl_compile_check(gsg, vert_path, frag_path, expect_fail=False): + """Compile supplied GLSL shader paths and check for errors""" + shader = core.Shader.load(core.Shader.SL_GLSL, vert_path, frag_path) + assert shader is not None + + shader.prepare_now(gsg.prepared_objects, gsg) + assert shader.is_prepared(gsg.prepared_objects) + if expect_fail: + assert shader.get_error_flag() + else: + assert not shader.get_error_flag() + + def test_glsl_test(gsg): "Test to make sure that the GLSL tests work correctly." @@ -329,3 +346,24 @@ def test_glsl_write_extract_image_buffer(gsg): assert struct.unpack('I', tex1.get_ram_image()) == (123,) assert struct.unpack('i', tex2.get_ram_image()) == (-456,) + + +def test_glsl_compile_error(gsg): + """Test getting compile errors from bad shaders""" + vert_path = core.Filename(SHADERS_DIR, 'glsl_bad.vert') + frag_path = core.Filename(SHADERS_DIR, 'glsl_simple.frag') + run_glsl_compile_check(gsg, vert_path, frag_path, expect_fail=True) + + +def test_glsl_from_file(gsg): + """Test compiling GLSL shaders from files""" + vert_path = core.Filename(SHADERS_DIR, 'glsl_simple.vert') + frag_path = core.Filename(SHADERS_DIR, 'glsl_simple.frag') + run_glsl_compile_check(gsg, vert_path, frag_path) + + +def test_glsl_includes(gsg): + """Test preprocessing includes in GLSL shaders""" + vert_path = core.Filename(SHADERS_DIR, 'glsl_include.vert') + frag_path = core.Filename(SHADERS_DIR, 'glsl_simple.frag') + run_glsl_compile_check(gsg, vert_path, frag_path) From c395460390215299dc3798ba0134e4667920285d Mon Sep 17 00:00:00 2001 From: fireclawthefox Date: Fri, 2 Aug 2019 23:29:56 +0200 Subject: [PATCH 3/6] directtools: Added missing imports Closes #698 --- direct/src/directtools/DirectUtil.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/direct/src/directtools/DirectUtil.py b/direct/src/directtools/DirectUtil.py index 9919f841b2..2a244e325c 100644 --- a/direct/src/directtools/DirectUtil.py +++ b/direct/src/directtools/DirectUtil.py @@ -1,5 +1,7 @@ from .DirectGlobals import * +from panda3d.core import VBase4 +from direct.task.Task import Task # Routines to adjust values def ROUND_TO(value, divisor): From 2b64a7d74fe6daba7709538cb56fea6b0f5eb7a0 Mon Sep 17 00:00:00 2001 From: fireclawthefox Date: Fri, 2 Aug 2019 23:23:01 +0200 Subject: [PATCH 4/6] dgui: Scrollbar width changeable after initialization Closes #699 --- direct/src/gui/DirectScrolledFrame.py | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/direct/src/gui/DirectScrolledFrame.py b/direct/src/gui/DirectScrolledFrame.py index d5274de6fe..2c60ed950f 100644 --- a/direct/src/gui/DirectScrolledFrame.py +++ b/direct/src/gui/DirectScrolledFrame.py @@ -33,7 +33,7 @@ class DirectScrolledFrame(DirectFrame): ('canvasSize', (-1, 1, -1, 1), self.setCanvasSize), ('manageScrollBars', 1, self.setManageScrollBars), ('autoHideScrollBars', 1, self.setAutoHideScrollBars), - ('scrollBarWidth', 0.08, None), + ('scrollBarWidth', 0.08, self.setScrollBarWidth), ('borderWidth', (0.01, 0.01), self.setBorderWidth), ) @@ -72,6 +72,11 @@ class DirectScrolledFrame(DirectFrame): # Call option initialization functions self.initialiseoptions(DirectScrolledFrame) + def setScrollBarWidth(self): + w = self['scrollBarWidth'] + self.verticalScroll["frameSize"] = (-w / 2.0, w / 2.0, -1, 1) + self.horizontalScroll["frameSize"] = (-1, 1, -w / 2.0, w / 2.0) + def setCanvasSize(self): f = self['canvasSize'] self.guiItem.setVirtualFrame(f[0], f[1], f[2], f[3]) From 42dff65e4d50ca5d78ef04ea56b65952c39e62c9 Mon Sep 17 00:00:00 2001 From: rdb Date: Sat, 3 Aug 2019 10:32:40 +0200 Subject: [PATCH 5/6] general: fix various unprotected debug() outputs These should be protected by an is_debug() check so that they can be optimized out properly in a release build. Setting check-debug-notify-protect in Config.prc can be used to track down cases of missed checks. --- panda/src/audiotraits/openalAudioManager.cxx | 8 +- panda/src/glstuff/glGraphicsBuffer_src.cxx | 24 ++++-- .../glstuff/glGraphicsStateGuardian_src.cxx | 10 ++- panda/src/gobj/shader.cxx | 18 ++-- panda/src/movies/movieTypeRegistry.cxx | 4 +- panda/src/pnmimagetypes/pnmFileTypePNG.cxx | 82 ++++++++++++------- 6 files changed, 95 insertions(+), 51 deletions(-) diff --git a/panda/src/audiotraits/openalAudioManager.cxx b/panda/src/audiotraits/openalAudioManager.cxx index edf7dfe222..c3c64b1c57 100644 --- a/panda/src/audiotraits/openalAudioManager.cxx +++ b/panda/src/audiotraits/openalAudioManager.cxx @@ -252,7 +252,9 @@ select_audio_device() { devices = (const char *)alcGetString(nullptr, ALC_ALL_DEVICES_SPECIFIER); if (devices) { - audio_cat.debug() << "All OpenAL devices:\n"; + if (audio_cat.is_debug()) { + audio_cat.debug() << "All OpenAL devices:\n"; + } while (*devices) { string device(devices); @@ -280,7 +282,9 @@ select_audio_device() { devices = (const char *)alcGetString(nullptr, ALC_DEVICE_SPECIFIER); if (devices) { - audio_cat.debug() << "OpenAL drivers:\n"; + if (audio_cat.is_debug()) { + audio_cat.debug() << "OpenAL drivers:\n"; + } while (*devices) { string device(devices); diff --git a/panda/src/glstuff/glGraphicsBuffer_src.cxx b/panda/src/glstuff/glGraphicsBuffer_src.cxx index b85a3e76c1..d5252944f5 100644 --- a/panda/src/glstuff/glGraphicsBuffer_src.cxx +++ b/panda/src/glstuff/glGraphicsBuffer_src.cxx @@ -778,7 +778,9 @@ bind_slot(int layer, bool rb_resize, Texture **attach, RenderTexturePlane slot, } if (attachpoint == GL_DEPTH_ATTACHMENT_EXT) { - GLCAT.debug() << "Binding texture " << *tex << " to depth attachment.\n"; + if (GLCAT.is_debug()) { + GLCAT.debug() << "Binding texture " << *tex << " to depth attachment.\n"; + } attach_tex(layer, 0, tex, GL_DEPTH_ATTACHMENT_EXT); @@ -789,7 +791,9 @@ bind_slot(int layer, bool rb_resize, Texture **attach, RenderTexturePlane slot, #endif if (slot == RTP_depth_stencil) { - GLCAT.debug() << "Binding texture " << *tex << " to stencil attachment.\n"; + if (GLCAT.is_debug()) { + GLCAT.debug() << "Binding texture " << *tex << " to stencil attachment.\n"; + } attach_tex(layer, 0, tex, GL_STENCIL_ATTACHMENT_EXT); @@ -801,7 +805,9 @@ bind_slot(int layer, bool rb_resize, Texture **attach, RenderTexturePlane slot, } } else { - GLCAT.debug() << "Binding texture " << *tex << " to color attachment.\n"; + if (GLCAT.is_debug()) { + GLCAT.debug() << "Binding texture " << *tex << " to color attachment.\n"; + } attach_tex(layer, 0, tex, attachpoint); @@ -988,7 +994,9 @@ bind_slot(int layer, bool rb_resize, Texture **attach, RenderTexturePlane slot, glgsg->_glBindRenderbuffer(GL_RENDERBUFFER_EXT, _rb[slot]); if (slot == RTP_depth_stencil) { - GLCAT.debug() << "Creating depth stencil renderbuffer.\n"; + if (GLCAT.is_debug()) { + GLCAT.debug() << "Creating depth stencil renderbuffer.\n"; + } // Allocate renderbuffer storage for depth stencil. GLint depth_size = 0, stencil_size = 0; glgsg->_glRenderbufferStorage(GL_RENDERBUFFER_EXT, gl_format, _rb_size_x, _rb_size_y); @@ -1014,7 +1022,9 @@ bind_slot(int layer, bool rb_resize, Texture **attach, RenderTexturePlane slot, report_my_gl_errors(); } else if (slot == RTP_depth) { - GLCAT.debug() << "Creating depth renderbuffer.\n"; + if (GLCAT.is_debug()) { + GLCAT.debug() << "Creating depth renderbuffer.\n"; + } // Allocate renderbuffer storage for regular depth. GLint depth_size = 0; glgsg->_glRenderbufferStorage(GL_RENDERBUFFER_EXT, gl_format, _rb_size_x, _rb_size_y); @@ -1052,7 +1062,9 @@ bind_slot(int layer, bool rb_resize, Texture **attach, RenderTexturePlane slot, report_my_gl_errors(); } else { - GLCAT.debug() << "Creating color renderbuffer.\n"; + if (GLCAT.is_debug()) { + GLCAT.debug() << "Creating color renderbuffer.\n"; + } glgsg->_glRenderbufferStorage(GL_RENDERBUFFER_EXT, gl_format, _rb_size_x, _rb_size_y); GLint red_size = 0, green_size = 0, blue_size = 0, alpha_size = 0; diff --git a/panda/src/glstuff/glGraphicsStateGuardian_src.cxx b/panda/src/glstuff/glGraphicsStateGuardian_src.cxx index 3ad8e01428..c913d1ff34 100644 --- a/panda/src/glstuff/glGraphicsStateGuardian_src.cxx +++ b/panda/src/glstuff/glGraphicsStateGuardian_src.cxx @@ -722,10 +722,12 @@ reset() { || has_extension("GL_KHR_debug") || has_extension("GL_ARB_debug_output"); - if (_supports_debug) { - GLCAT.debug() << "gl-debug supported, but NOT enabled.\n"; - } else { - GLCAT.debug() << "gl-debug disabled and unsupported.\n"; + if (GLCAT.is_debug()) { + if (_supports_debug) { + GLCAT.debug() << "gl-debug supported, but NOT enabled.\n"; + } else { + GLCAT.debug() << "gl-debug disabled and unsupported.\n"; + } } } diff --git a/panda/src/gobj/shader.cxx b/panda/src/gobj/shader.cxx index d42e6a4734..a60a7e169b 100644 --- a/panda/src/gobj/shader.cxx +++ b/panda/src/gobj/shader.cxx @@ -3274,8 +3274,10 @@ load(const Filename &file, ShaderLanguage lang) { shader_cat.info() << "Shader " << file << " was modified on disk, reloading.\n"; } else { - shader_cat.debug() - << "Shader " << file << " was found in shader cache.\n"; + if (shader_cat.is_debug()) { + shader_cat.debug() + << "Shader " << file << " was found in shader cache.\n"; + } return i->second; } } @@ -3312,8 +3314,10 @@ load(ShaderLanguage lang, const Filename &vertex, shader_cat.info() << "Shader was modified on disk, reloading.\n"; } else { - shader_cat.debug() - << "Shader was found in shader cache.\n"; + if (shader_cat.is_debug()) { + shader_cat.debug() + << "Shader was found in shader cache.\n"; + } return i->second; } } @@ -3365,8 +3369,10 @@ load_compute(ShaderLanguage lang, const Filename &fn) { shader_cat.info() << "Compute shader " << fn << " was modified on disk, reloading.\n"; } else { - shader_cat.debug() - << "Compute shader " << fn << " was found in shader cache.\n"; + if (shader_cat.is_debug()) { + shader_cat.debug() + << "Compute shader " << fn << " was found in shader cache.\n"; + } return i->second; } } diff --git a/panda/src/movies/movieTypeRegistry.cxx b/panda/src/movies/movieTypeRegistry.cxx index dca0ef9400..64acc8e42a 100644 --- a/panda/src/movies/movieTypeRegistry.cxx +++ b/panda/src/movies/movieTypeRegistry.cxx @@ -90,7 +90,7 @@ register_audio_type(MakeAudioFunc func, const string &extensions) { if (_audio_type_registry.count(*wi)) { movies_cat->warning() << "Attempt to register multiple audio types with extension " << (*wi) << "\n"; - } else { + } else if (movies_cat->is_debug()) { movies_cat->debug() << "Registered audio type with extension " << (*wi) << "\n"; } @@ -219,7 +219,7 @@ register_video_type(MakeVideoFunc func, const string &extensions) { if (_video_type_registry.count(*wi)) { movies_cat->warning() << "Attempt to register multiple video types with extension " << (*wi) << "\n"; - } else { + } else if (movies_cat->is_debug()) { movies_cat->debug() << "Registered video type with extension " << (*wi) << "\n"; } diff --git a/panda/src/pnmimagetypes/pnmFileTypePNG.cxx b/panda/src/pnmimagetypes/pnmFileTypePNG.cxx index 7d64faed50..e4b144dd95 100644 --- a/panda/src/pnmimagetypes/pnmFileTypePNG.cxx +++ b/panda/src/pnmimagetypes/pnmFileTypePNG.cxx @@ -227,10 +227,12 @@ Reader(PNMFileType *type, istream *file, bool owns_file, string magic_number) : } } - pnmimage_png_cat.debug() - << "width = " << width << " height = " << height << " bit_depth = " - << bit_depth << " color_type = " << color_type - << " color_space = " << _color_space << "\n"; + if (pnmimage_png_cat.is_debug()) { + pnmimage_png_cat.debug() + << "width = " << width << " height = " << height << " bit_depth = " + << bit_depth << " color_type = " << color_type + << " color_space = " << _color_space << "\n"; + } _x_size = width; _y_size = height; @@ -242,32 +244,42 @@ Reader(PNMFileType *type, istream *file, bool owns_file, string magic_number) : switch (color_type) { case PNG_COLOR_TYPE_GRAY: - pnmimage_png_cat.debug() - << "PNG_COLOR_TYPE_GRAY\n"; + if (pnmimage_png_cat.is_debug()) { + pnmimage_png_cat.debug() + << "PNG_COLOR_TYPE_GRAY\n"; + } _num_channels = 1; break; case PNG_COLOR_TYPE_GRAY_ALPHA: - pnmimage_png_cat.debug() - << "PNG_COLOR_TYPE_GRAY_ALPHA\n"; + if (pnmimage_png_cat.is_debug()) { + pnmimage_png_cat.debug() + << "PNG_COLOR_TYPE_GRAY_ALPHA\n"; + } _num_channels = 2; break; case PNG_COLOR_TYPE_RGB: - pnmimage_png_cat.debug() - << "PNG_COLOR_TYPE_RGB\n"; + if (pnmimage_png_cat.is_debug()) { + pnmimage_png_cat.debug() + << "PNG_COLOR_TYPE_RGB\n"; + } _num_channels = 3; break; case PNG_COLOR_TYPE_RGB_ALPHA: - pnmimage_png_cat.debug() - << "PNG_COLOR_TYPE_RGB_ALPHA\n"; + if (pnmimage_png_cat.is_debug()) { + pnmimage_png_cat.debug() + << "PNG_COLOR_TYPE_RGB_ALPHA\n"; + } _num_channels = 4; break; case PNG_COLOR_TYPE_PALETTE: - pnmimage_png_cat.debug() - << "PNG_COLOR_TYPE_PALETTE\n"; + if (pnmimage_png_cat.is_debug()) { + pnmimage_png_cat.debug() + << "PNG_COLOR_TYPE_PALETTE\n"; + } png_set_palette_to_rgb(_png); _maxval = 255; _num_channels = 3; @@ -566,8 +578,10 @@ write_data(xel *array, xelval *alpha_data) { if (png_palette) { if (png_bit_depth <= 8) { if (compute_palette(palette, array, alpha_data, png_max_palette)) { - pnmimage_png_cat.debug() - << palette.size() << " colors found.\n"; + if (pnmimage_png_cat.is_debug()) { + pnmimage_png_cat.debug() + << palette.size() << " colors found.\n"; + } int palette_bit_depth = make_png_bit_depth(pm_maxvaltobits(palette.size() - 1)); @@ -581,10 +595,12 @@ write_data(xel *array, xelval *alpha_data) { if (palette_bit_depth < total_bits || _maxval != (1 << true_bit_depth) - 1) { - pnmimage_png_cat.debug() - << "palette bit depth of " << palette_bit_depth - << " improves on bit depth of " << total_bits - << "; making a palette image.\n"; + if (pnmimage_png_cat.is_debug()) { + pnmimage_png_cat.debug() + << "palette bit depth of " << palette_bit_depth + << " improves on bit depth of " << total_bits + << "; making a palette image.\n"; + } color_type = PNG_COLOR_TYPE_PALETTE; @@ -611,36 +627,40 @@ write_data(xel *array, xelval *alpha_data) { png_set_PLTE(_png, _info, png_palette_table, palette.size()); if (has_alpha()) { - pnmimage_png_cat.debug() - << "palette contains " << num_alpha << " transparent entries.\n"; + if (pnmimage_png_cat.is_debug()) { + pnmimage_png_cat.debug() + << "palette contains " << num_alpha << " transparent entries.\n"; + } png_set_tRNS(_png, _info, png_trans, num_alpha, nullptr); } - } else { + } else if (pnmimage_png_cat.is_debug()) { pnmimage_png_cat.debug() << "palette bit depth of " << palette_bit_depth << " does not improve on bit depth of " << total_bits << "; not making a palette image.\n"; } - } else { + } else if (pnmimage_png_cat.is_debug()) { pnmimage_png_cat.debug() << "more than " << png_max_palette << " colors found; not making a palette image.\n"; } - } else { + } else if (pnmimage_png_cat.is_debug()) { pnmimage_png_cat.debug() << "maxval exceeds 255; not making a palette image.\n"; } - } else { + } else if (pnmimage_png_cat.is_debug()) { pnmimage_png_cat.debug() << "palette images are not enabled.\n"; } - pnmimage_png_cat.debug() - << "width = " << _x_size << " height = " << _y_size - << " maxval = " << _maxval << " bit_depth = " - << png_bit_depth << " color_type = " << color_type - << " color_space = " << _color_space << "\n"; + if (pnmimage_png_cat.is_debug()) { + pnmimage_png_cat.debug() + << "width = " << _x_size << " height = " << _y_size + << " maxval = " << _maxval << " bit_depth = " + << png_bit_depth << " color_type = " << color_type + << " color_space = " << _color_space << "\n"; + } png_set_IHDR(_png, _info, _x_size, _y_size, png_bit_depth, color_type, PNG_INTERLACE_NONE, From a86bdcfe3f9bfc832ac409701888539229d21f16 Mon Sep 17 00:00:00 2001 From: rdb Date: Sat, 3 Aug 2019 10:34:11 +0200 Subject: [PATCH 6/6] notify: support setting notify-output after static init time Previously it was only possible to set this in the default-loaded Config.prc file; now it is possible to set this at any time, though it can only be set once from its default value and not changed after it has already been set to something other than the default value. --- dtool/src/prc/notify.cxx | 24 +++++++++++++----------- dtool/src/prc/notifyCategory.cxx | 6 ++++++ 2 files changed, 19 insertions(+), 11 deletions(-) diff --git a/dtool/src/prc/notify.cxx b/dtool/src/prc/notify.cxx index f9c39135e8..690910ef4a 100644 --- a/dtool/src/prc/notify.cxx +++ b/dtool/src/prc/notify.cxx @@ -19,6 +19,7 @@ #include "filename.h" #include "config_prc.h" +#include #include #ifdef BUILD_IPHONE @@ -422,28 +423,29 @@ string_severity(const string &str) { */ void Notify:: config_initialized() { - static bool already_initialized = false; - if (already_initialized) { - nout << "Notify::config_initialized() called more than once.\n"; - return; - } - already_initialized = true; + // We allow this to be called more than once to allow the user to specify a + // notify-output even after the initial import of Panda3D modules. However, + // it cannot be changed after the first time it is set. if (_ostream_ptr == &cerr) { - ConfigVariableFilename notify_output + static ConfigVariableFilename notify_output ("notify-output", "", "The filename to which to write all the output of notify"); - if (!notify_output.empty()) { - if (notify_output == "stdout") { + // We use this to ensure that only one thread can initialize the output. + static std::atomic_flag initialized = ATOMIC_FLAG_INIT; + + std::string value = notify_output.get_value(); + if (!value.empty() && !initialized.test_and_set()) { + if (value == "stdout") { cout.setf(std::ios::unitbuf); set_ostream_ptr(&cout, false); - } else if (notify_output == "stderr") { + } else if (value == "stderr") { set_ostream_ptr(&cerr, false); } else { - Filename filename = notify_output; + Filename filename = value; filename.set_text(); #ifdef BUILD_IPHONE // On the iPhone, route everything through cerr, and then send cerr to diff --git a/dtool/src/prc/notifyCategory.cxx b/dtool/src/prc/notifyCategory.cxx index 3d856ceb08..86bf63f736 100644 --- a/dtool/src/prc/notifyCategory.cxx +++ b/dtool/src/prc/notifyCategory.cxx @@ -181,10 +181,16 @@ update_severity_cache() { } else { // Unless, of course, we're the root. _severity_cache = NS_info; + + // Take this opportunity to have Notify check whether the notify-output + // variable changed. + Notify::ptr()->config_initialized(); } } else { _severity_cache = _severity; + Notify::ptr()->config_initialized(); } + mark_cache_valid(_local_modified); }