Chrome 中启用的硬件加速阻止 canvas 使用 Fabricjs 显示矢量图像
Hardware Acceleration enabled in Chrome prevents canvas from displaying vector image with Fabricjs
我有一个应用程序(使用 Fabricjs)允许用户在 canvas 上绘图。他们将自己的名字画在 canvas 上,然后单击“保存”。我在 canvas 上调用 toSVG() 并获取 svg 字符串并将其存储在我的数据库中。
用户随后可以将该 SVG 字符串添加到新的 canvas,我调用...
fabric.loadSVGFromString(svg_string, function(objects, options) {
var group = new fabric.PathGroup(objects, options);
canvas.add(group);
canvas.calcOffset();
canvas.renderAll();
group.setCoords();
});
将 svg 图像添加到 canvas 就好了,类型是 'path-group'。
现在当用户点击 'save' 我调用 var my_string = canvas.toObject()
。然后我将那个 json 字符串提交到我的服务器并用 JSON.stringify(my_string)
.
保存它
SVG 现在已转换为 JSON,我将整个 JSON 字符串存储在数据库中。
我允许用户返回并再次编辑该 canvas 图像。我将 json 字符串加载到 canvas 中...
var json = my_string;
var serialized = (typeof json === 'string') ? JSON.parse(json) : json;
canvas.loadFromJSON(serialized, function(){
canvas.renderAll.bind(canvas);
});
直到大约一个月前,这在 Chrome 中工作得很好。它仍然会很好地加载图像和文本,它甚至会向 canvas 添加一个 'path-group' 对象。但是,路径组不显示。
在 Safari 和 Firefox 以及 IE 中都能正常显示。
我使用的是 Fabric 1.4.9,现在我已经升级到 1.5.0(只是为了看看它是否能解决问题)然后我升级到 1.6.0.rc1。它仍然无法在 Chrome 中使用,但可以在 Safari 和 Firefox 中使用。
因此它将读取和解析 SVG 并将其转换为 JSON 然后将其添加到 canvas 就好了但是当从 JSON 字符串添加它时它会阻塞。
正如 asturur 指出的那样。如果您在 Chrome 设置中禁用了硬件加速,这将在 Chrome 中再次起作用。
这是一个JS Fiddle
打开 Chrome 中的 link,您会发现它不会显示。在 Safari 或 Firefox 中打开它,您会看到“Travis”。如果您在 Chrome 中禁用硬件加速,它将按预期工作。
更新:
我知道这是我的几个用户计算机上的一个错误,但对于它的价值,这里是 chrome://gpu
的输出。
Graphics Feature Status
Canvas: Hardware accelerated
Flash: Hardware accelerated
Flash Stage3D: Hardware accelerated
Flash Stage3D Baseline profile: Hardware accelerated
Compositing: Hardware accelerated
Multiple Raster Threads: Enabled
Rasterization: Software only. Hardware acceleration disabled
Video Decode: Hardware accelerated
Video Encode: Hardware accelerated
WebGL: Hardware accelerated
Driver Bug Workarounds
disable_multimonitor_multisampling
gl_begin_gl_end_on_fbo_change_to_backbuffer
init_varyings_without_static_use
max_cube_map_texture_size_limit_1024
regenerate_struct_names
scalarize_vec_and_mat_constructor_args
unfold_short_circuit_as_ternary_operation
validate_multisample_buffer_allocation
Problems Detected
Limit max cube map texure size to 1024 on Macs with Intel GPUs
Applied Workarounds: max_cube_map_texture_size_limit_1024
Multisampling is buggy on OSX when multiple monitors are connected: 237931
Applied Workarounds: disable_multimonitor_multisampling
Multisampled renderbuffer allocation must be validated on some Macs: 290391
Applied Workarounds: validate_multisample_buffer_allocation
Unfold short circuit on Mac OS X: 307751
Applied Workarounds: unfold_short_circuit_as_ternary_operation
Mac drivers handle varyings without static use incorrectly: 322760
Applied Workarounds: init_varyings_without_static_use
Always rewrite vec/mat constructors to be consistent: 398694
Applied Workarounds: scalarize_vec_and_mat_constructor_args
Mac drivers handle struct scopes incorrectly: 403957
Applied Workarounds: regenerate_struct_names
glBindFramebuffer sometimes requires a glBegin/End to take effect: 435786
Applied Workarounds: gl_begin_gl_end_on_fbo_change_to_backbuffer
Accelerated rasterization has been disabled, either via about:flags or command line.
Disabled Features: rasterization
Version Information
Data exported 9/22/2015, 1:07:56 AM
Chrome version Chrome/45.0.2454.99
Operating system Mac OS X 10.10.5
Software rendering list version 10.9
Driver bug list version 8.19
ANGLE commit id 6f0fd8c5457f
2D graphics backend Skia
Command Line Args Chrome.app/Contents/MacOS/Google Chrome --enable-avfoundation --enable-avfoundation --flag-switches-begin --flag-switches-end
Driver Information
Initialization time 1
Sandboxed true
GPU0 VENDOR = 0x8086, DEVICE= 0x0a2e *ACTIVE*
Optimus false
AMD switchable false
Driver vendor
Driver version 10.6.33
Driver date
Pixel shader version 1.20
Vertex shader version 1.20
Max. MSAA samples 8
Machine model name MacBookPro
Machine model version 11.1
GL_VENDOR Intel Inc.
GL_RENDERER Intel Iris OpenGL Engine
GL_VERSION 2.1 INTEL-10.6.33
GL_EXTENSIONS GL_ARB_color_buffer_float GL_ARB_depth_buffer_float GL_ARB_depth_clamp GL_ARB_depth_texture GL_ARB_draw_buffers GL_ARB_draw_elements_base_vertex GL_ARB_draw_instanced GL_ARB_fragment_program GL_ARB_fragment_program_shadow GL_ARB_fragment_shader GL_ARB_framebuffer_object GL_ARB_framebuffer_sRGB GL_ARB_half_float_pixel GL_ARB_half_float_vertex GL_ARB_instanced_arrays GL_ARB_multisample GL_ARB_multitexture GL_ARB_occlusion_query GL_ARB_pixel_buffer_object GL_ARB_point_parameters GL_ARB_point_sprite GL_ARB_provoking_vertex GL_ARB_seamless_cube_map GL_ARB_shader_objects GL_ARB_shader_texture_lod GL_ARB_shading_language_100 GL_ARB_shadow GL_ARB_sync GL_ARB_texture_border_clamp GL_ARB_texture_compression GL_ARB_texture_compression_rgtc GL_ARB_texture_cube_map GL_ARB_texture_env_add GL_ARB_texture_env_combine GL_ARB_texture_env_crossbar GL_ARB_texture_env_dot3 GL_ARB_texture_float GL_ARB_texture_mirrored_repeat GL_ARB_texture_non_power_of_two GL_ARB_texture_rectangle GL_ARB_texture_rg GL_ARB_transpose_matrix GL_ARB_vertex_array_bgra GL_ARB_vertex_blend GL_ARB_vertex_buffer_object GL_ARB_vertex_program GL_ARB_vertex_shader GL_ARB_window_pos GL_EXT_abgr GL_EXT_bgra GL_EXT_blend_color GL_EXT_blend_equation_separate GL_EXT_blend_func_separate GL_EXT_blend_minmax GL_EXT_blend_subtract GL_EXT_clip_volume_hint GL_EXT_debug_label GL_EXT_debug_marker GL_EXT_draw_buffers2 GL_EXT_draw_range_elements GL_EXT_fog_coord GL_EXT_framebuffer_blit GL_EXT_framebuffer_multisample GL_EXT_framebuffer_multisample_blit_scaled GL_EXT_framebuffer_object GL_EXT_framebuffer_sRGB GL_EXT_geometry_shader4 GL_EXT_gpu_program_parameters GL_EXT_gpu_shader4 GL_EXT_multi_draw_arrays GL_EXT_packed_depth_stencil GL_EXT_packed_float GL_EXT_provoking_vertex GL_EXT_rescale_normal GL_EXT_secondary_color GL_EXT_separate_specular_color GL_EXT_shadow_funcs GL_EXT_stencil_two_side GL_EXT_stencil_wrap GL_EXT_texture_array GL_EXT_texture_compression_dxt1 GL_EXT_texture_compression_s3tc GL_EXT_texture_env_add GL_EXT_texture_filter_anisotropic GL_EXT_texture_integer GL_EXT_texture_lod_bias GL_EXT_texture_rectangle GL_EXT_texture_shared_exponent GL_EXT_texture_sRGB GL_EXT_texture_sRGB_decode GL_EXT_timer_query GL_EXT_transform_feedback GL_EXT_vertex_array_bgra GL_APPLE_aux_depth_stencil GL_APPLE_client_storage GL_APPLE_element_array GL_APPLE_fence GL_APPLE_float_pixels GL_APPLE_flush_buffer_range GL_APPLE_flush_render GL_APPLE_object_purgeable GL_APPLE_packed_pixels GL_APPLE_pixel_buffer GL_APPLE_rgb_422 GL_APPLE_row_bytes GL_APPLE_specular_vector GL_APPLE_texture_range GL_APPLE_transform_hint GL_APPLE_vertex_array_object GL_APPLE_vertex_array_range GL_APPLE_vertex_point_size GL_APPLE_vertex_program_evaluators GL_APPLE_ycbcr_422 GL_ATI_separate_stencil GL_ATI_texture_env_combine3 GL_ATI_texture_float GL_ATI_texture_mirror_once GL_IBM_rasterpos_clip GL_NV_blend_square GL_NV_conditional_render GL_NV_depth_clamp GL_NV_fog_distance GL_NV_light_max_exponent GL_NV_texgen_reflection GL_NV_texture_barrier GL_SGIS_generate_mipmap GL_SGIS_texture_edge_clamp GL_SGIS_texture_lod
Disabled Extensions
Window system binding vendor
Window system binding version
Window system binding extensions
Direct rendering Yes
Reset notification strategy 0x0000
GPU process crash count 0
事实证明,Chrome 在 strokeDashArray 中测试空值的方式存在问题。
在我的每个路径对象上,我都有这样的 strokeDashArray...
"strokeDashArray": [null, null ]
改成这个解决了问题...
"strokeDashArray": null
或者对这个...
"strokeDashArray": [1, 0 ]
// this is not recommended as it *could* hurt performance for no reason.
我仍然向 Chromium 团队提交了工单,我看到他们发现了问题并修复了它。因此,在 chrome 的未来版本中,当用户启用硬件加速时,[null, null ] 应该可以正常工作。这在未来可能不相关,但我想也许有一天谷歌人会找到这个 question/answer 并且它会对他们有所帮助。
我有一个应用程序(使用 Fabricjs)允许用户在 canvas 上绘图。他们将自己的名字画在 canvas 上,然后单击“保存”。我在 canvas 上调用 toSVG() 并获取 svg 字符串并将其存储在我的数据库中。
用户随后可以将该 SVG 字符串添加到新的 canvas,我调用...
fabric.loadSVGFromString(svg_string, function(objects, options) {
var group = new fabric.PathGroup(objects, options);
canvas.add(group);
canvas.calcOffset();
canvas.renderAll();
group.setCoords();
});
将 svg 图像添加到 canvas 就好了,类型是 'path-group'。
现在当用户点击 'save' 我调用 var my_string = canvas.toObject()
。然后我将那个 json 字符串提交到我的服务器并用 JSON.stringify(my_string)
.
SVG 现在已转换为 JSON,我将整个 JSON 字符串存储在数据库中。
我允许用户返回并再次编辑该 canvas 图像。我将 json 字符串加载到 canvas 中...
var json = my_string;
var serialized = (typeof json === 'string') ? JSON.parse(json) : json;
canvas.loadFromJSON(serialized, function(){
canvas.renderAll.bind(canvas);
});
直到大约一个月前,这在 Chrome 中工作得很好。它仍然会很好地加载图像和文本,它甚至会向 canvas 添加一个 'path-group' 对象。但是,路径组不显示。
在 Safari 和 Firefox 以及 IE 中都能正常显示。
我使用的是 Fabric 1.4.9,现在我已经升级到 1.5.0(只是为了看看它是否能解决问题)然后我升级到 1.6.0.rc1。它仍然无法在 Chrome 中使用,但可以在 Safari 和 Firefox 中使用。
因此它将读取和解析 SVG 并将其转换为 JSON 然后将其添加到 canvas 就好了但是当从 JSON 字符串添加它时它会阻塞。
正如 asturur 指出的那样。如果您在 Chrome 设置中禁用了硬件加速,这将在 Chrome 中再次起作用。
这是一个JS Fiddle
打开 Chrome 中的 link,您会发现它不会显示。在 Safari 或 Firefox 中打开它,您会看到“Travis”。如果您在 Chrome 中禁用硬件加速,它将按预期工作。
更新:
我知道这是我的几个用户计算机上的一个错误,但对于它的价值,这里是 chrome://gpu
的输出。
Graphics Feature Status
Canvas: Hardware accelerated
Flash: Hardware accelerated
Flash Stage3D: Hardware accelerated
Flash Stage3D Baseline profile: Hardware accelerated
Compositing: Hardware accelerated
Multiple Raster Threads: Enabled
Rasterization: Software only. Hardware acceleration disabled
Video Decode: Hardware accelerated
Video Encode: Hardware accelerated
WebGL: Hardware accelerated
Driver Bug Workarounds
disable_multimonitor_multisampling
gl_begin_gl_end_on_fbo_change_to_backbuffer
init_varyings_without_static_use
max_cube_map_texture_size_limit_1024
regenerate_struct_names
scalarize_vec_and_mat_constructor_args
unfold_short_circuit_as_ternary_operation
validate_multisample_buffer_allocation
Problems Detected
Limit max cube map texure size to 1024 on Macs with Intel GPUs
Applied Workarounds: max_cube_map_texture_size_limit_1024
Multisampling is buggy on OSX when multiple monitors are connected: 237931
Applied Workarounds: disable_multimonitor_multisampling
Multisampled renderbuffer allocation must be validated on some Macs: 290391
Applied Workarounds: validate_multisample_buffer_allocation
Unfold short circuit on Mac OS X: 307751
Applied Workarounds: unfold_short_circuit_as_ternary_operation
Mac drivers handle varyings without static use incorrectly: 322760
Applied Workarounds: init_varyings_without_static_use
Always rewrite vec/mat constructors to be consistent: 398694
Applied Workarounds: scalarize_vec_and_mat_constructor_args
Mac drivers handle struct scopes incorrectly: 403957
Applied Workarounds: regenerate_struct_names
glBindFramebuffer sometimes requires a glBegin/End to take effect: 435786
Applied Workarounds: gl_begin_gl_end_on_fbo_change_to_backbuffer
Accelerated rasterization has been disabled, either via about:flags or command line.
Disabled Features: rasterization
Version Information
Data exported 9/22/2015, 1:07:56 AM
Chrome version Chrome/45.0.2454.99
Operating system Mac OS X 10.10.5
Software rendering list version 10.9
Driver bug list version 8.19
ANGLE commit id 6f0fd8c5457f
2D graphics backend Skia
Command Line Args Chrome.app/Contents/MacOS/Google Chrome --enable-avfoundation --enable-avfoundation --flag-switches-begin --flag-switches-end
Driver Information
Initialization time 1
Sandboxed true
GPU0 VENDOR = 0x8086, DEVICE= 0x0a2e *ACTIVE*
Optimus false
AMD switchable false
Driver vendor
Driver version 10.6.33
Driver date
Pixel shader version 1.20
Vertex shader version 1.20
Max. MSAA samples 8
Machine model name MacBookPro
Machine model version 11.1
GL_VENDOR Intel Inc.
GL_RENDERER Intel Iris OpenGL Engine
GL_VERSION 2.1 INTEL-10.6.33
GL_EXTENSIONS GL_ARB_color_buffer_float GL_ARB_depth_buffer_float GL_ARB_depth_clamp GL_ARB_depth_texture GL_ARB_draw_buffers GL_ARB_draw_elements_base_vertex GL_ARB_draw_instanced GL_ARB_fragment_program GL_ARB_fragment_program_shadow GL_ARB_fragment_shader GL_ARB_framebuffer_object GL_ARB_framebuffer_sRGB GL_ARB_half_float_pixel GL_ARB_half_float_vertex GL_ARB_instanced_arrays GL_ARB_multisample GL_ARB_multitexture GL_ARB_occlusion_query GL_ARB_pixel_buffer_object GL_ARB_point_parameters GL_ARB_point_sprite GL_ARB_provoking_vertex GL_ARB_seamless_cube_map GL_ARB_shader_objects GL_ARB_shader_texture_lod GL_ARB_shading_language_100 GL_ARB_shadow GL_ARB_sync GL_ARB_texture_border_clamp GL_ARB_texture_compression GL_ARB_texture_compression_rgtc GL_ARB_texture_cube_map GL_ARB_texture_env_add GL_ARB_texture_env_combine GL_ARB_texture_env_crossbar GL_ARB_texture_env_dot3 GL_ARB_texture_float GL_ARB_texture_mirrored_repeat GL_ARB_texture_non_power_of_two GL_ARB_texture_rectangle GL_ARB_texture_rg GL_ARB_transpose_matrix GL_ARB_vertex_array_bgra GL_ARB_vertex_blend GL_ARB_vertex_buffer_object GL_ARB_vertex_program GL_ARB_vertex_shader GL_ARB_window_pos GL_EXT_abgr GL_EXT_bgra GL_EXT_blend_color GL_EXT_blend_equation_separate GL_EXT_blend_func_separate GL_EXT_blend_minmax GL_EXT_blend_subtract GL_EXT_clip_volume_hint GL_EXT_debug_label GL_EXT_debug_marker GL_EXT_draw_buffers2 GL_EXT_draw_range_elements GL_EXT_fog_coord GL_EXT_framebuffer_blit GL_EXT_framebuffer_multisample GL_EXT_framebuffer_multisample_blit_scaled GL_EXT_framebuffer_object GL_EXT_framebuffer_sRGB GL_EXT_geometry_shader4 GL_EXT_gpu_program_parameters GL_EXT_gpu_shader4 GL_EXT_multi_draw_arrays GL_EXT_packed_depth_stencil GL_EXT_packed_float GL_EXT_provoking_vertex GL_EXT_rescale_normal GL_EXT_secondary_color GL_EXT_separate_specular_color GL_EXT_shadow_funcs GL_EXT_stencil_two_side GL_EXT_stencil_wrap GL_EXT_texture_array GL_EXT_texture_compression_dxt1 GL_EXT_texture_compression_s3tc GL_EXT_texture_env_add GL_EXT_texture_filter_anisotropic GL_EXT_texture_integer GL_EXT_texture_lod_bias GL_EXT_texture_rectangle GL_EXT_texture_shared_exponent GL_EXT_texture_sRGB GL_EXT_texture_sRGB_decode GL_EXT_timer_query GL_EXT_transform_feedback GL_EXT_vertex_array_bgra GL_APPLE_aux_depth_stencil GL_APPLE_client_storage GL_APPLE_element_array GL_APPLE_fence GL_APPLE_float_pixels GL_APPLE_flush_buffer_range GL_APPLE_flush_render GL_APPLE_object_purgeable GL_APPLE_packed_pixels GL_APPLE_pixel_buffer GL_APPLE_rgb_422 GL_APPLE_row_bytes GL_APPLE_specular_vector GL_APPLE_texture_range GL_APPLE_transform_hint GL_APPLE_vertex_array_object GL_APPLE_vertex_array_range GL_APPLE_vertex_point_size GL_APPLE_vertex_program_evaluators GL_APPLE_ycbcr_422 GL_ATI_separate_stencil GL_ATI_texture_env_combine3 GL_ATI_texture_float GL_ATI_texture_mirror_once GL_IBM_rasterpos_clip GL_NV_blend_square GL_NV_conditional_render GL_NV_depth_clamp GL_NV_fog_distance GL_NV_light_max_exponent GL_NV_texgen_reflection GL_NV_texture_barrier GL_SGIS_generate_mipmap GL_SGIS_texture_edge_clamp GL_SGIS_texture_lod
Disabled Extensions
Window system binding vendor
Window system binding version
Window system binding extensions
Direct rendering Yes
Reset notification strategy 0x0000
GPU process crash count 0
事实证明,Chrome 在 strokeDashArray 中测试空值的方式存在问题。
在我的每个路径对象上,我都有这样的 strokeDashArray...
"strokeDashArray": [null, null ]
改成这个解决了问题...
"strokeDashArray": null
或者对这个...
"strokeDashArray": [1, 0 ]
// this is not recommended as it *could* hurt performance for no reason.
我仍然向 Chromium 团队提交了工单,我看到他们发现了问题并修复了它。因此,在 chrome 的未来版本中,当用户启用硬件加速时,[null, null ] 应该可以正常工作。这在未来可能不相关,但我想也许有一天谷歌人会找到这个 question/answer 并且它会对他们有所帮助。