diff options
Diffstat (limited to 'drivers/gles3/rasterizer_canvas_gles3.cpp')
-rw-r--r-- | drivers/gles3/rasterizer_canvas_gles3.cpp | 239 |
1 files changed, 91 insertions, 148 deletions
diff --git a/drivers/gles3/rasterizer_canvas_gles3.cpp b/drivers/gles3/rasterizer_canvas_gles3.cpp index 441b049b50..e14018c562 100644 --- a/drivers/gles3/rasterizer_canvas_gles3.cpp +++ b/drivers/gles3/rasterizer_canvas_gles3.cpp @@ -117,6 +117,7 @@ void RasterizerCanvasGLES3::_update_transform_to_mat4(const Transform3D &p_trans void RasterizerCanvasGLES3::canvas_render_items(RID p_to_render_target, Item *p_item_list, const Color &p_modulate, Light *p_light_list, Light *p_directional_list, const Transform2D &p_canvas_transform, RS::CanvasItemTextureFilter p_default_filter, RS::CanvasItemTextureRepeat p_default_repeat, bool p_snap_2d_vertices_to_pixel, bool &r_sdf_used) { GLES3::TextureStorage *texture_storage = GLES3::TextureStorage::get_singleton(); + GLES3::MaterialStorage *material_storage = GLES3::MaterialStorage::get_singleton(); texture_storage->frame.current_rt = nullptr; @@ -155,7 +156,7 @@ void RasterizerCanvasGLES3::canvas_render_items(RID p_to_render_target, Item *p_ state_buffer.screen_pixel_size[0] = 1.0 / render_target_size.x; state_buffer.screen_pixel_size[1] = 1.0 / render_target_size.y; - state_buffer.time = texture_storage->frame.time; + state_buffer.time = state.time; state_buffer.use_pixel_snap = p_snap_2d_vertices_to_pixel; state_buffer.directional_light_count = 0; //directional_light_count; @@ -178,8 +179,12 @@ void RasterizerCanvasGLES3::canvas_render_items(RID p_to_render_target, Item *p_ //print_line("w: " + itos(ssize.width) + " s: " + rtos(canvas_scale)); state_buffer.tex_to_sdf = 1.0 / ((canvas_scale.x + canvas_scale.y) * 0.5); - glBindBufferBase(GL_UNIFORM_BUFFER, 0, state.canvas_state_buffer); + glBindBufferBase(GL_UNIFORM_BUFFER, BASE_UNIFORM_BUFFER_OBJECT, state.canvas_state_buffer); glBufferData(GL_UNIFORM_BUFFER, sizeof(StateBuffer), &state_buffer, GL_STREAM_DRAW); + + GLuint global_buffer = material_storage->global_variables_get_uniform_buffer(); + + glBindBufferBase(GL_UNIFORM_BUFFER, GLOBAL_UNIFORM_BUFFER_OBJECT, global_buffer); glBindBuffer(GL_UNIFORM_BUFFER, 0); } @@ -197,8 +202,6 @@ void RasterizerCanvasGLES3::canvas_render_items(RID p_to_render_target, Item *p_ r_sdf_used = false; int item_count = 0; - glActiveTexture(GL_TEXTURE0); - glBindTexture(GL_TEXTURE_2D, storage->resources.white_tex); Item *ci = p_item_list; while (ci) { // just add all items for now @@ -215,7 +218,6 @@ void RasterizerCanvasGLES3::canvas_render_items(RID p_to_render_target, Item *p_ } void RasterizerCanvasGLES3::_render_items(RID p_to_render_target, int p_item_count, const Transform2D &p_canvas_transform_inverse, Light *p_lights, bool p_to_backbuffer) { - GLES3::TextureStorage *texture_storage = GLES3::TextureStorage::get_singleton(); GLES3::MaterialStorage *material_storage = GLES3::MaterialStorage::get_singleton(); Item *current_clip = nullptr; @@ -229,88 +231,31 @@ void RasterizerCanvasGLES3::_render_items(RID p_to_render_target, int p_item_cou RID prev_material; uint32_t index = 0; + state.current_shader_version = state.canvas_shader_default_version; + for (int i = 0; i < p_item_count; i++) { Item *ci = items[i]; RID material = ci->material_owner == nullptr ? ci->material : ci->material_owner->material; - GLES3::Material *material_ptr = material_storage->get_material(material); if (material.is_null() && ci->canvas_group != nullptr) { material = default_canvas_group_material; } if (material != prev_material) { - GLES3::Shader *shader_ptr = nullptr; - - if (material_ptr) { - shader_ptr = material_ptr->shader; - - if (shader_ptr && shader_ptr->mode != RS::SHADER_CANVAS_ITEM) { - shader_ptr = nullptr; // not a canvas item shader, don't use. - } + GLES3::CanvasMaterialData *material_data = nullptr; + if (material.is_valid()) { + material_data = static_cast<GLES3::CanvasMaterialData *>(material_storage->material_get_data(material, RS::SHADER_CANVAS_ITEM)); } - - if (shader_ptr) { - if (true) { //check that shader has changed - if (shader_ptr->canvas_item.uses_time) { - RenderingServerDefault::redraw_request(); - } - //state.canvas_shader.version_bind_shader(shader_ptr->version, CanvasShaderGLES3::MODE_QUAD); - state.current_shader_version = shader_ptr->version; - } - - int tc = material_ptr->textures.size(); - Pair<StringName, RID> *textures = material_ptr->textures.ptrw(); - - ShaderCompiler::GeneratedCode::Texture *texture_uniforms = shader_ptr->texture_uniforms.ptrw(); - - for (int ti = 0; ti < tc; i++) { - glActiveTexture(GL_TEXTURE0 + ti); - - GLES3::Texture *t = texture_storage->get_texture(textures[ti].second); - - if (!t) { - switch (texture_uniforms[i].hint) { - case ShaderLanguage::ShaderNode::Uniform::HINT_BLACK_ALBEDO: - case ShaderLanguage::ShaderNode::Uniform::HINT_BLACK: { - glBindTexture(GL_TEXTURE_2D, storage->resources.black_tex); - } break; - case ShaderLanguage::ShaderNode::Uniform::HINT_ANISOTROPY: { - glBindTexture(GL_TEXTURE_2D, storage->resources.aniso_tex); - } break; - case ShaderLanguage::ShaderNode::Uniform::HINT_NORMAL: { - glBindTexture(GL_TEXTURE_2D, storage->resources.normal_tex); - } break; - default: { - glBindTexture(GL_TEXTURE_2D, storage->resources.white_tex); - } break; - } - - continue; - } - - //Set texture filter and repeat texture_uniforms[i].filter texture_uniforms[i].repeat - - if (t->redraw_if_visible) { - RenderingServerDefault::redraw_request(); - } - - t = t->get_ptr(); - -#ifdef TOOLS_ENABLED - if (t->detect_normal && texture_uniforms[i].hint == ShaderLanguage::ShaderNode::Uniform::HINT_NORMAL) { - t->detect_normal(t->detect_normal_ud); - } -#endif - if (t->render_target) { - t->render_target->used_in_frame = true; - } - - glBindTexture(t->target, t->tex_id); + if (material_data) { + if (material_data->shader_data->version.is_valid() && material_data->shader_data->valid) { + // Bind uniform buffer and textures + material_data->bind_uniforms(); + state.current_shader_version = material_data->shader_data->version; + } else { + state.current_shader_version = state.canvas_shader_default_version; } - } else { - //state.canvas_shader.version_bind_shader(state.canvas_shader_default_version, CanvasShaderGLES3::MODE_QUAD); state.current_shader_version = state.canvas_shader_default_version; } prev_material = material; @@ -389,7 +334,7 @@ void RasterizerCanvasGLES3::_render_item(RID p_render_target, const Item *p_item state.current_command = Item::Command::TYPE_RECT; } _bind_canvas_texture(rect->texture, current_filter, current_repeat, r_index, last_texture, texpixel_size); - state.canvas_shader.version_bind_shader(state.current_shader_version, CanvasShaderGLES3::MODE_QUAD); + GLES3::MaterialStorage::get_singleton()->shaders.canvas_shader.version_bind_shader(state.current_shader_version, CanvasShaderGLES3::MODE_QUAD); Rect2 src_rect; Rect2 dst_rect; @@ -552,7 +497,7 @@ void RasterizerCanvasGLES3::_render_item(RID p_render_target, const Item *p_item state.current_command = Item::Command::TYPE_POLYGON; } _bind_canvas_texture(polygon->texture, current_filter, current_repeat, r_index, last_texture, texpixel_size); - state.canvas_shader.version_bind_shader(state.current_shader_version, CanvasShaderGLES3::MODE_ATTRIBUTES); + GLES3::MaterialStorage::get_singleton()->shaders.canvas_shader.version_bind_shader(state.current_shader_version, CanvasShaderGLES3::MODE_ATTRIBUTES); state.current_primitive = polygon->primitive; state.instance_data_array[r_index].modulation[0] = base_color.r; @@ -566,16 +511,18 @@ void RasterizerCanvasGLES3::_render_item(RID p_render_target, const Item *p_item state.instance_data_array[r_index].ninepatch_margins[j] = 0; } - // If the previous operation is not done yet, allocated a new buffer - GLint syncStatus; - glGetSynciv(state.fences[state.current_buffer], GL_SYNC_STATUS, sizeof(GLint), nullptr, &syncStatus); - if (syncStatus == GL_UNSIGNALED) { - _allocate_instance_data_buffer(); - } else { - glDeleteSync(state.fences[state.current_buffer]); + // If the previous operation is not done yet, allocate a new buffer + if (state.fences[state.current_buffer] != GLsync()) { + GLint syncStatus; + glGetSynciv(state.fences[state.current_buffer], GL_SYNC_STATUS, sizeof(GLint), nullptr, &syncStatus); + if (syncStatus == GL_UNSIGNALED) { + _allocate_instance_data_buffer(); + } else { + glDeleteSync(state.fences[state.current_buffer]); + } } - glBindBufferBase(GL_UNIFORM_BUFFER, 3, state.canvas_instance_data_buffers[state.current_buffer]); + glBindBufferBase(GL_UNIFORM_BUFFER, INSTANCE_UNIFORM_BUFFER_OBJECT, state.canvas_instance_data_buffers[state.current_buffer]); #ifdef JAVASCRIPT_ENABLED //WebGL 2.0 does not support mapping buffers, so use slow glBufferData instead glBufferData(GL_UNIFORM_BUFFER, sizeof(InstanceData), &state.instance_data_array[0], GL_DYNAMIC_DRAW); @@ -609,7 +556,7 @@ void RasterizerCanvasGLES3::_render_item(RID p_render_target, const Item *p_item state.current_command = Item::Command::TYPE_PRIMITIVE; } _bind_canvas_texture(RID(), current_filter, current_repeat, r_index, last_texture, texpixel_size); - state.canvas_shader.version_bind_shader(state.current_shader_version, CanvasShaderGLES3::MODE_PRIMITIVE); + GLES3::MaterialStorage::get_singleton()->shaders.canvas_shader.version_bind_shader(state.current_shader_version, CanvasShaderGLES3::MODE_PRIMITIVE); for (uint32_t j = 0; j < MIN(3u, primitive->point_count); j++) { state.instance_data_array[r_index].points[j * 2 + 0] = primitive->points[j].x; @@ -771,15 +718,17 @@ void RasterizerCanvasGLES3::_render_item(RID p_render_target, const Item *p_item void RasterizerCanvasGLES3::_render_batch(uint32_t &r_index) { if (state.end_batch && r_index > 0) { // If the previous operation is not done yet, allocate a new buffer - GLint syncStatus; - glGetSynciv(state.fences[state.current_buffer], GL_SYNC_STATUS, sizeof(GLint), nullptr, &syncStatus); - if (syncStatus == GL_UNSIGNALED) { - _allocate_instance_data_buffer(); - } else { - glDeleteSync(state.fences[state.current_buffer]); + if (state.fences[state.current_buffer] != GLsync()) { + GLint syncStatus; + glGetSynciv(state.fences[state.current_buffer], GL_SYNC_STATUS, sizeof(GLint), nullptr, &syncStatus); + if (syncStatus == GL_UNSIGNALED) { + _allocate_instance_data_buffer(); + } else { + glDeleteSync(state.fences[state.current_buffer]); + } } - glBindBufferBase(GL_UNIFORM_BUFFER, 3, state.canvas_instance_data_buffers[state.current_buffer]); + glBindBufferBase(GL_UNIFORM_BUFFER, INSTANCE_UNIFORM_BUFFER_OBJECT, state.canvas_instance_data_buffers[state.current_buffer]); #ifdef JAVASCRIPT_ENABLED //WebGL 2.0 does not support mapping buffers, so use slow glBufferData instead glBufferData(GL_UNIFORM_BUFFER, sizeof(InstanceData) * r_index, state.instance_data_array, GL_DYNAMIC_DRAW); @@ -823,24 +772,24 @@ void RasterizerCanvasGLES3::_render_batch(uint32_t &r_index) { } // TODO maybe dont use -void RasterizerCanvasGLES3::_end_batch(uint32_t &r_index) { +void RasterizerCanvasGLES3::_end_batch(const uint32_t p_index) { for (int i = 0; i < 4; i++) { - state.instance_data_array[r_index].modulation[i] = 0.0; - state.instance_data_array[r_index].ninepatch_margins[i] = 0.0; - state.instance_data_array[r_index].src_rect[i] = 0.0; - state.instance_data_array[r_index].dst_rect[i] = 0.0; + state.instance_data_array[p_index].modulation[i] = 0.0; + state.instance_data_array[p_index].ninepatch_margins[i] = 0.0; + state.instance_data_array[p_index].src_rect[i] = 0.0; + state.instance_data_array[p_index].dst_rect[i] = 0.0; } - state.instance_data_array[r_index].flags = uint32_t(0); - state.instance_data_array[r_index].color_texture_pixel_size[0] = 0.0; - state.instance_data_array[r_index].color_texture_pixel_size[1] = 0.0; + state.instance_data_array[p_index].flags = uint32_t(0); + state.instance_data_array[p_index].color_texture_pixel_size[0] = 0.0; + state.instance_data_array[p_index].color_texture_pixel_size[1] = 0.0; - state.instance_data_array[r_index].pad[0] = 0.0; - state.instance_data_array[r_index].pad[1] = 0.0; + state.instance_data_array[p_index].pad[0] = 0.0; + state.instance_data_array[p_index].pad[1] = 0.0; - state.instance_data_array[r_index].lights[0] = uint32_t(0); - state.instance_data_array[r_index].lights[1] = uint32_t(0); - state.instance_data_array[r_index].lights[2] = uint32_t(0); - state.instance_data_array[r_index].lights[3] = uint32_t(0); + state.instance_data_array[p_index].lights[0] = uint32_t(0); + state.instance_data_array[p_index].lights[1] = uint32_t(0); + state.instance_data_array[p_index].lights[2] = uint32_t(0); + state.instance_data_array[p_index].lights[3] = uint32_t(0); } RID RasterizerCanvasGLES3::light_create() { @@ -903,7 +852,8 @@ void RasterizerCanvasGLES3::canvas_begin() { reset_canvas(); glActiveTexture(GL_TEXTURE0); - glBindTexture(GL_TEXTURE_2D, storage->resources.white_tex); + GLES3::Texture *tex = texture_storage->get_texture(texture_storage->texture_gl_get_default(GLES3::DEFAULT_GL_TEXTURE_WHITE)); + glBindTexture(GL_TEXTURE_2D, tex->tex_id); } void RasterizerCanvasGLES3::canvas_end() { @@ -961,11 +911,9 @@ void RasterizerCanvasGLES3::_bind_canvas_texture(RID p_texture, RS::CanvasItemTe ct->size_cache = Size2i(1, 1); glActiveTexture(GL_TEXTURE0); - glBindTexture(GL_TEXTURE_2D, storage->resources.white_tex); - + GLES3::Texture *tex = texture_storage->get_texture(texture_storage->texture_gl_get_default(GLES3::DEFAULT_GL_TEXTURE_WHITE)); + glBindTexture(GL_TEXTURE_2D, tex->tex_id); } else { - texture = texture->get_ptr(); - glActiveTexture(GL_TEXTURE0); glBindTexture(GL_TEXTURE_2D, texture->tex_id); @@ -973,8 +921,8 @@ void RasterizerCanvasGLES3::_bind_canvas_texture(RID p_texture, RS::CanvasItemTe state.current_tex_ptr = texture; ct->size_cache = Size2i(texture->width, texture->height); - texture->GLSetFilter(GL_TEXTURE_2D, filter); - texture->GLSetRepeat(GL_TEXTURE_2D, repeat); + texture->gl_set_filter(filter); + texture->gl_set_repeat(repeat); } GLES3::Texture *normal_map = texture_storage->get_texture(ct->normal_map); @@ -983,17 +931,16 @@ void RasterizerCanvasGLES3::_bind_canvas_texture(RID p_texture, RS::CanvasItemTe state.current_normal = RID(); ct->use_normal_cache = false; glActiveTexture(GL_TEXTURE0 + GLES3::Config::get_singleton()->max_texture_image_units - 6); - glBindTexture(GL_TEXTURE_2D, storage->resources.normal_tex); + GLES3::Texture *tex = texture_storage->get_texture(texture_storage->texture_gl_get_default(GLES3::DEFAULT_GL_TEXTURE_NORMAL)); + glBindTexture(GL_TEXTURE_2D, tex->tex_id); } else { - normal_map = normal_map->get_ptr(); - glActiveTexture(GL_TEXTURE0 + storage->config->max_texture_image_units - 6); glBindTexture(GL_TEXTURE_2D, normal_map->tex_id); state.current_normal = ct->normal_map; ct->use_normal_cache = true; - texture->GLSetFilter(GL_TEXTURE_2D, filter); - texture->GLSetRepeat(GL_TEXTURE_2D, repeat); + texture->gl_set_filter(filter); + texture->gl_set_repeat(repeat); } GLES3::Texture *specular_map = texture_storage->get_texture(ct->specular); @@ -1002,17 +949,15 @@ void RasterizerCanvasGLES3::_bind_canvas_texture(RID p_texture, RS::CanvasItemTe state.current_specular = RID(); ct->use_specular_cache = false; glActiveTexture(GL_TEXTURE0 + storage->config->max_texture_image_units - 7); - glBindTexture(GL_TEXTURE_2D, storage->resources.white_tex); - + GLES3::Texture *tex = texture_storage->get_texture(texture_storage->texture_gl_get_default(GLES3::DEFAULT_GL_TEXTURE_WHITE)); + glBindTexture(GL_TEXTURE_2D, tex->tex_id); } else { - specular_map = specular_map->get_ptr(); - glActiveTexture(GL_TEXTURE0 + storage->config->max_texture_image_units - 7); glBindTexture(GL_TEXTURE_2D, specular_map->tex_id); state.current_specular = ct->specular; ct->use_specular_cache = true; - texture->GLSetFilter(GL_TEXTURE_2D, filter); - texture->GLSetRepeat(GL_TEXTURE_2D, repeat); + texture->gl_set_filter(filter); + texture->gl_set_repeat(repeat); } if (ct->use_specular_cache) { @@ -1102,8 +1047,8 @@ RendererCanvasRender::PolygonID RasterizerCanvasGLES3::request_polygon(const Vec { glBindBuffer(GL_ARRAY_BUFFER, pb.vertex_buffer); glBufferData(GL_ARRAY_BUFFER, stride * vertex_count * sizeof(float), nullptr, GL_STATIC_DRAW); // TODO may not be necessary - const uint8_t *r = polygon_buffer.ptr(); - float *fptr = (float *)r; + uint8_t *r = polygon_buffer.ptrw(); + float *fptr = reinterpret_cast<float *>(r); uint32_t *uptr = (uint32_t *)r; uint32_t base_offset = 0; { @@ -1260,7 +1205,19 @@ void RasterizerCanvasGLES3::_allocate_instance_data_buffer() { glBindBuffer(GL_UNIFORM_BUFFER, 0); } -void RasterizerCanvasGLES3::initialize() { +void RasterizerCanvasGLES3::set_time(double p_time) { + state.time = p_time; +} + +RasterizerCanvasGLES3 *RasterizerCanvasGLES3::singleton = nullptr; + +RasterizerCanvasGLES3 *RasterizerCanvasGLES3::get_singleton() { + return singleton; +} + +RasterizerCanvasGLES3::RasterizerCanvasGLES3(RasterizerStorageGLES3 *p_storage) { + singleton = this; + storage = p_storage; GLES3::TextureStorage *texture_storage = GLES3::TextureStorage::get_singleton(); GLES3::MaterialStorage *material_storage = GLES3::MaterialStorage::get_singleton(); @@ -1386,9 +1343,7 @@ void RasterizerCanvasGLES3::initialize() { } //state.canvas_shadow_shader.init(); - - int uniform_max_size; - glGetIntegerv(GL_MAX_UNIFORM_BLOCK_SIZE, &uniform_max_size); + int uniform_max_size = storage->config->max_uniform_buffer_size; if (uniform_max_size < 65536) { state.max_lights_per_render = 64; state.max_instances_per_batch = 128; @@ -1402,6 +1357,7 @@ void RasterizerCanvasGLES3::initialize() { state.fences.resize(64); glGenBuffers(64, state.canvas_instance_data_buffers.ptr()); for (int i = 0; i < 64; i++) { + state.fences[i] = GLsync(); glBindBuffer(GL_UNIFORM_BUFFER, state.canvas_instance_data_buffers[i]); glBufferData(GL_UNIFORM_BUFFER, sizeof(InstanceData) * state.max_instances_per_batch, nullptr, GL_DYNAMIC_DRAW); } @@ -1419,9 +1375,9 @@ void RasterizerCanvasGLES3::initialize() { global_defines += "#define MAX_LIGHTS " + itos(state.max_instances_per_batch) + "\n"; global_defines += "#define MAX_DRAW_DATA_INSTANCES " + itos(state.max_instances_per_batch) + "\n"; - state.canvas_shader.initialize(global_defines); - state.canvas_shader_default_version = state.canvas_shader.version_create(); - state.canvas_shader.version_bind_shader(state.canvas_shader_default_version, CanvasShaderGLES3::MODE_QUAD); + GLES3::MaterialStorage::get_singleton()->shaders.canvas_shader.initialize(global_defines); + state.canvas_shader_default_version = GLES3::MaterialStorage::get_singleton()->shaders.canvas_shader.version_create(); + GLES3::MaterialStorage::get_singleton()->shaders.canvas_shader.version_bind_shader(state.canvas_shader_default_version, CanvasShaderGLES3::MODE_QUAD); //state.canvas_shader.set_conditional(CanvasOldShaderGLES3::USE_RGBA_SHADOWS, storage->config->use_rgba_2d_shadows); @@ -1463,32 +1419,19 @@ void fragment() { state.using_transparent_rt = false; state.using_skeleton = false; state.current_shader_version = state.canvas_shader_default_version; -} - -RasterizerCanvasGLES3 *RasterizerCanvasGLES3::singleton = nullptr; - -RasterizerCanvasGLES3 *RasterizerCanvasGLES3::get_singleton() { - return singleton; -} - -RasterizerCanvasGLES3::RasterizerCanvasGLES3(RasterizerStorageGLES3 *p_storage) { - singleton = this; - storage = p_storage; - initialize(); + state.time = 0.0; } RasterizerCanvasGLES3::~RasterizerCanvasGLES3() { GLES3::TextureStorage *texture_storage = GLES3::TextureStorage::get_singleton(); GLES3::MaterialStorage *material_storage = GLES3::MaterialStorage::get_singleton(); - state.canvas_shader.version_free(state.canvas_shader_default_version); + GLES3::MaterialStorage::get_singleton()->shaders.canvas_shader.version_free(state.canvas_shader_default_version); material_storage->material_free(default_canvas_group_material); material_storage->shader_free(default_canvas_group_shader); texture_storage->canvas_texture_free(default_canvas_texture); singleton = nullptr; -} -void RasterizerCanvasGLES3::finalize() { glDeleteBuffers(1, &data.canvas_quad_vertices); glDeleteVertexArrays(1, &data.canvas_quad_array); |