Changeset View
Changeset View
Standalone View
Standalone View
intern/cycles/blender/display_driver.cpp
| Show First 20 Lines • Show All 474 Lines • ▼ Show 20 Lines | public: | ||||
| bool gl_resources_ensure() | bool gl_resources_ensure() | ||||
| { | { | ||||
| if (!texture.gl_resources_ensure()) { | if (!texture.gl_resources_ensure()) { | ||||
| gl_resources_destroy(); | gl_resources_destroy(); | ||||
| return false; | return false; | ||||
| } | } | ||||
| if (!gl_vertex_buffer) { | |||||
| glGenBuffers(1, &gl_vertex_buffer); | |||||
| if (!gl_vertex_buffer) { | |||||
| LOG(ERROR) << "Error allocating tile VBO."; | |||||
| gl_resources_destroy(); | |||||
| return false; | |||||
| } | |||||
| } | |||||
| return true; | return true; | ||||
| } | } | ||||
| void gl_resources_destroy() | void gl_resources_destroy() | ||||
| { | { | ||||
| texture.gl_resources_destroy(); | texture.gl_resources_destroy(); | ||||
| if (gl_vertex_buffer) { | |||||
| glDeleteBuffers(1, &gl_vertex_buffer); | |||||
| gl_vertex_buffer = 0; | |||||
| } | |||||
| } | } | ||||
| inline bool ready_to_draw() const | inline bool ready_to_draw() const | ||||
| { | { | ||||
| return texture.gl_id != 0; | return texture.gl_id != 0; | ||||
| } | } | ||||
| /* Texture which contains pixels of the tile. */ | /* Texture which contains pixels of the tile. */ | ||||
| GLTexture texture; | GLTexture texture; | ||||
| /* Display parameters the texture of this tile has been updated for. */ | /* Display parameters the texture of this tile has been updated for. */ | ||||
| BlenderDisplayDriver::Params params; | BlenderDisplayDriver::Params params; | ||||
| /* OpenGL resources needed for drawing. */ | |||||
| uint gl_vertex_buffer = 0; | |||||
| }; | }; | ||||
| class DrawTileAndPBO { | class DrawTileAndPBO { | ||||
| public: | public: | ||||
| bool gl_resources_ensure() | bool gl_resources_ensure() | ||||
| { | { | ||||
| if (!tile.gl_resources_ensure() || !buffer_object.gl_resources_ensure()) { | if (!tile.gl_resources_ensure() || !buffer_object.gl_resources_ensure()) { | ||||
| gl_resources_destroy(); | gl_resources_destroy(); | ||||
| Show All 29 Lines | struct { | ||||
| { | { | ||||
| for (DrawTile &tile : tiles) { | for (DrawTile &tile : tiles) { | ||||
| tile.gl_resources_destroy(); | tile.gl_resources_destroy(); | ||||
| } | } | ||||
| tiles.clear(); | tiles.clear(); | ||||
| } | } | ||||
| } finished_tiles; | } finished_tiles; | ||||
| /* OpenGL vertex buffer needed for drawing. */ | |||||
| uint gl_vertex_buffer = 0; | |||||
| bool gl_resources_ensure() | |||||
| { | |||||
| if (!gl_vertex_buffer) { | |||||
| glGenBuffers(1, &gl_vertex_buffer); | |||||
| if (!gl_vertex_buffer) { | |||||
| LOG(ERROR) << "Error allocating tile VBO."; | |||||
| return false; | |||||
| } | |||||
| } | |||||
| return true; | |||||
| } | |||||
| void gl_resources_destroy() | |||||
| { | |||||
| if (gl_vertex_buffer) { | |||||
| glDeleteBuffers(1, &gl_vertex_buffer); | |||||
| gl_vertex_buffer = 0; | |||||
| } | |||||
| } | |||||
| }; | }; | ||||
| BlenderDisplayDriver::BlenderDisplayDriver(BL::RenderEngine &b_engine, BL::Scene &b_scene) | BlenderDisplayDriver::BlenderDisplayDriver(BL::RenderEngine &b_engine, BL::Scene &b_scene) | ||||
| : b_engine_(b_engine), | : b_engine_(b_engine), | ||||
| display_shader_(BlenderDisplayShader::create(b_engine, b_scene)), | display_shader_(BlenderDisplayShader::create(b_engine, b_scene)), | ||||
| tiles_(make_unique<Tiles>()) | tiles_(make_unique<Tiles>()) | ||||
| { | { | ||||
| /* Create context while on the main thread. */ | /* Create context while on the main thread. */ | ||||
| ▲ Show 20 Lines • Show All 50 Lines • ▼ Show 20 Lines | bool BlenderDisplayDriver::update_begin(const Params ¶ms, | ||||
| /* Clear storage of all finished tiles when display clear is requested. | /* Clear storage of all finished tiles when display clear is requested. | ||||
| * Do it when new tile data is provided to handle the display clear flag in a single place. | * Do it when new tile data is provided to handle the display clear flag in a single place. | ||||
| * It also makes the logic reliable from the whether drawing did happen or not point of view. */ | * It also makes the logic reliable from the whether drawing did happen or not point of view. */ | ||||
| if (need_clear_) { | if (need_clear_) { | ||||
| tiles_->finished_tiles.gl_resources_destroy_and_clear(); | tiles_->finished_tiles.gl_resources_destroy_and_clear(); | ||||
| need_clear_ = false; | need_clear_ = false; | ||||
| } | } | ||||
| if (!tiles_->gl_resources_ensure()) { | |||||
| tiles_->gl_resources_destroy(); | |||||
| gl_context_disable(); | |||||
| return false; | |||||
| } | |||||
| if (!tiles_->current_tile.gl_resources_ensure()) { | if (!tiles_->current_tile.gl_resources_ensure()) { | ||||
| tiles_->current_tile.gl_resources_destroy(); | tiles_->current_tile.gl_resources_destroy(); | ||||
| gl_context_disable(); | gl_context_disable(); | ||||
| return false; | return false; | ||||
| } | } | ||||
| /* Update texture dimensions if needed. */ | /* Update texture dimensions if needed. */ | ||||
| if (current_tile.texture.width != texture_width || | if (current_tile.texture.width != texture_width || | ||||
| ▲ Show 20 Lines • Show All 183 Lines • ▼ Show 20 Lines | static void vertex_buffer_update(const DisplayDriver::Params ¶ms) | ||||
| vpointer[15] = y + height; | vpointer[15] = y + height; | ||||
| glUnmapBuffer(GL_ARRAY_BUFFER); | glUnmapBuffer(GL_ARRAY_BUFFER); | ||||
| } | } | ||||
| static void draw_tile(const float2 &zoom, | static void draw_tile(const float2 &zoom, | ||||
| const int texcoord_attribute, | const int texcoord_attribute, | ||||
| const int position_attribute, | const int position_attribute, | ||||
| const DrawTile &draw_tile) | const DrawTile &draw_tile, | ||||
| const uint gl_vertex_buffer) | |||||
| { | { | ||||
| if (!draw_tile.ready_to_draw()) { | if (!draw_tile.ready_to_draw()) { | ||||
| return; | return; | ||||
| } | } | ||||
| const GLTexture &texture = draw_tile.texture; | const GLTexture &texture = draw_tile.texture; | ||||
| DCHECK_NE(texture.gl_id, 0); | DCHECK_NE(texture.gl_id, 0); | ||||
| DCHECK_NE(draw_tile.gl_vertex_buffer, 0); | DCHECK_NE(gl_vertex_buffer, 0); | ||||
| glBindBuffer(GL_ARRAY_BUFFER, draw_tile.gl_vertex_buffer); | glBindBuffer(GL_ARRAY_BUFFER, gl_vertex_buffer); | ||||
| /* Draw at the parameters for which the texture has been updated for. This allows to always draw | /* Draw at the parameters for which the texture has been updated for. This allows to always draw | ||||
| * texture during bordered-rendered camera view without flickering. The validness of the display | * texture during bordered-rendered camera view without flickering. The validness of the display | ||||
| * parameters for a texture is guaranteed by the initial "clear" state which makes drawing to | * parameters for a texture is guaranteed by the initial "clear" state which makes drawing to | ||||
| * have an early output. | * have an early output. | ||||
| * | * | ||||
| * Such approach can cause some extra "jelly" effect during panning, but it is not more jelly | * Such approach can cause some extra "jelly" effect during panning, but it is not more jelly | ||||
| * than overlay of selected objects. Also, it's possible to redraw texture at an intersection of | * than overlay of selected objects. Also, it's possible to redraw texture at an intersection of | ||||
| ▲ Show 20 Lines • Show All 103 Lines • ▼ Show 20 Lines | void BlenderDisplayDriver::draw(const Params ¶ms) | ||||
| display_shader_->bind(params.full_size.x, params.full_size.y); | display_shader_->bind(params.full_size.x, params.full_size.y); | ||||
| const int texcoord_attribute = display_shader_->get_tex_coord_attrib_location(); | const int texcoord_attribute = display_shader_->get_tex_coord_attrib_location(); | ||||
| const int position_attribute = display_shader_->get_position_attrib_location(); | const int position_attribute = display_shader_->get_position_attrib_location(); | ||||
| glEnableVertexAttribArray(texcoord_attribute); | glEnableVertexAttribArray(texcoord_attribute); | ||||
| glEnableVertexAttribArray(position_attribute); | glEnableVertexAttribArray(position_attribute); | ||||
| draw_tile(zoom_, texcoord_attribute, position_attribute, tiles_->current_tile.tile); | draw_tile(zoom_, | ||||
| texcoord_attribute, | |||||
| position_attribute, | |||||
| tiles_->current_tile.tile, | |||||
| tiles_->gl_vertex_buffer); | |||||
| for (const DrawTile &tile : tiles_->finished_tiles.tiles) { | for (const DrawTile &tile : tiles_->finished_tiles.tiles) { | ||||
| draw_tile(zoom_, texcoord_attribute, position_attribute, tile); | draw_tile(zoom_, texcoord_attribute, position_attribute, tile, tiles_->gl_vertex_buffer); | ||||
| } | } | ||||
| display_shader_->unbind(); | display_shader_->unbind(); | ||||
| glBindTexture(GL_TEXTURE_2D, 0); | glBindTexture(GL_TEXTURE_2D, 0); | ||||
| glBindVertexArray(0); | glBindVertexArray(0); | ||||
| glBindBuffer(GL_ARRAY_BUFFER, 0); | glBindBuffer(GL_ARRAY_BUFFER, 0); | ||||
| ▲ Show 20 Lines • Show All 86 Lines • ▼ Show 20 Lines | |||||
| } | } | ||||
| void BlenderDisplayDriver::gl_resources_destroy() | void BlenderDisplayDriver::gl_resources_destroy() | ||||
| { | { | ||||
| gl_context_enable(); | gl_context_enable(); | ||||
| tiles_->current_tile.gl_resources_destroy(); | tiles_->current_tile.gl_resources_destroy(); | ||||
| tiles_->finished_tiles.gl_resources_destroy_and_clear(); | tiles_->finished_tiles.gl_resources_destroy_and_clear(); | ||||
| tiles_->gl_resources_destroy(); | |||||
| gl_context_disable(); | gl_context_disable(); | ||||
| gl_context_dispose(); | gl_context_dispose(); | ||||
| } | } | ||||
| CCL_NAMESPACE_END | CCL_NAMESPACE_END | ||||