37 if (b_engine.support_display_space_shader(b_scene)) {
38 return make_unique<BlenderDisplaySpaceShader>(b_engine, b_scene);
41 return make_unique<BlenderFallbackDisplayShader>();
69 "uniform vec2 fullscreen;\n"
72 "out vec2 texCoord_interp;\n"
74 "vec2 normalize_coordinates()\n"
76 " return (vec2(2.0) * (pos / fullscreen)) - vec2(1.0);\n"
81 " gl_Position = vec4(normalize_coordinates(), 0.0, 1.0);\n"
82 " texCoord_interp = texCoord;\n"
87 "uniform sampler2D image_texture;\n"
88 "in vec2 texCoord_interp;\n"
89 "out vec4 fragColor;\n"
93 " fragColor = texture(image_texture, texCoord_interp);\n"
98 LOG(ERROR) <<
"Shader: " <<
task <<
" error:";
99 LOG(ERROR) <<
"===== shader string ====";
101 stringstream stream(code);
105 while (getline(stream, partial,
'\n')) {
107 LOG(ERROR) <<
" " << line <<
" " << partial;
110 LOG(ERROR) << line <<
" " << partial;
125 const GLuint
program = glCreateProgram();
127 for (
int i = 0; i < 2; i++) {
128 const GLuint shader = glCreateShader(
shaders[i].
type);
130 string source_str =
shaders[i].source;
131 const char *c_str = source_str.c_str();
133 glShaderSource(shader, 1, &c_str,
NULL);
134 glCompileShader(shader);
136 GLint compile_status;
137 glGetShaderiv(shader, GL_COMPILE_STATUS, &compile_status);
139 if (!compile_status) {
147 glAttachShader(
program, shader);
151 glBindFragDataLocation(
program, 0,
"fragColor");
158 glGetProgramiv(
program, GL_LINK_STATUS, &link_status);
211 LOG(ERROR) <<
"Shader doesn't contain the 'image_texture' uniform.";
218 LOG(ERROR) <<
"Shader doesn't contain the 'fullscreen' uniform.";
236 : b_engine_(b_engine), b_scene_(b_scene)
254 glGetIntegerv(GL_CURRENT_PROGRAM,
reinterpret_cast<int *
>(&
shader_program_));
258 LOG(ERROR) <<
"Error retrieving shader program for display space shader.";
292 if (
this == &other) {
312 glGenTextures(1, &
gl_id);
314 LOG(ERROR) <<
"Error creating texture.";
319 glActiveTexture(GL_TEXTURE0);
320 glBindTexture(GL_TEXTURE_2D,
gl_id);
322 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
323 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
327 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
328 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
330 glBindTexture(GL_TEXTURE_2D, 0);
343 glDeleteTextures(1, &
gl_id);
392 if (
this == &other) {
411 glGenBuffers(1, &
gl_id);
413 LOG(ERROR) <<
"Error creating texture pixel buffer object.";
428 glDeleteBuffers(1, &
gl_id);
527 void gl_resources_destroy_and_clear()
530 tile.gl_resources_destroy();
545 LOG(ERROR) <<
"Error allocating tile VBO.";
563 : b_engine_(b_engine),
565 tiles_(make_unique<
Tiles>())
582 if (!
tiles_->current_tile.tile.ready_to_draw()) {
584 <<
"Unexpectedly moving to the next tile without any data provided for current tile.";
592 DCHECK(!
tiles_->current_tile.need_update_texture_pixels);
594 tiles_->finished_tiles.tiles.emplace_back(std::move(
tiles_->current_tile.tile));
624 tiles_->finished_tiles.gl_resources_destroy_and_clear();
628 if (!
tiles_->gl_resources_ensure()) {
629 tiles_->gl_resources_destroy();
634 if (!
tiles_->current_tile.gl_resources_ensure()) {
635 tiles_->current_tile.gl_resources_destroy();
643 glActiveTexture(GL_TEXTURE0);
644 glBindTexture(GL_TEXTURE_2D, current_tile.
texture.
gl_id);
646 GL_TEXTURE_2D, 0, GL_RGBA16F, texture_width, texture_height, 0, GL_RGBA, GL_HALF_FLOAT, 0);
649 glBindTexture(GL_TEXTURE_2D, 0);
661 const int buffer_width =
params.size.x;
662 const int buffer_height =
params.size.y;
663 if (current_tile_buffer_object.
width != buffer_width ||
664 current_tile_buffer_object.
height != buffer_height) {
665 const size_t size_in_bytes =
sizeof(
half4) * buffer_width * buffer_height;
666 glBindBuffer(GL_PIXEL_UNPACK_BUFFER, current_tile_buffer_object.
gl_id);
667 glBufferData(GL_PIXEL_UNPACK_BUFFER, size_in_bytes, 0, GL_DYNAMIC_DRAW);
668 glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0);
670 current_tile_buffer_object.
width = buffer_width;
671 current_tile_buffer_object.
height = buffer_height;
688 glActiveTexture(GL_TEXTURE0);
689 glBindTexture(GL_TEXTURE_2D, texture.
gl_id);
690 glBindBuffer(GL_PIXEL_UNPACK_BUFFER,
tile.buffer_object.gl_id);
693 GL_TEXTURE_2D, 0, 0, 0, texture.
width, texture.
height, GL_RGBA, GL_HALF_FLOAT, 0);
695 glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0);
696 glBindTexture(GL_TEXTURE_2D, 0);
717 tiles_->current_tile.need_update_texture_pixels =
true;
735 const uint pbo_gl_id =
tiles_->current_tile.buffer_object.gl_id;
739 glBindBuffer(GL_PIXEL_UNPACK_BUFFER, pbo_gl_id);
741 half4 *mapped_rgba_pixels =
reinterpret_cast<half4 *
>(
742 glMapBuffer(GL_PIXEL_UNPACK_BUFFER, GL_WRITE_ONLY));
743 if (!mapped_rgba_pixels) {
744 LOG(ERROR) <<
"Error mapping BlenderDisplayDriver pixel buffer object.";
747 return mapped_rgba_pixels;
752 glUnmapBuffer(GL_PIXEL_UNPACK_BUFFER);
754 glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0);
802 const int x =
params.full_offset.x;
803 const int y =
params.full_offset.y;
810 glBufferData(GL_ARRAY_BUFFER, 16 *
sizeof(
float),
NULL, GL_STREAM_DRAW);
812 float *vpointer =
reinterpret_cast<float *
>(glMapBuffer(GL_ARRAY_BUFFER, GL_WRITE_ONLY));
837 glUnmapBuffer(GL_ARRAY_BUFFER);
841 const int texcoord_attribute,
842 const int position_attribute,
844 const uint gl_vertex_buffer)
855 glBindBuffer(GL_ARRAY_BUFFER, gl_vertex_buffer);
868 glBindTexture(GL_TEXTURE_2D, texture.
gl_id);
878 const float zoomed_width =
draw_tile.params.size.x * zoom.
x;
879 const float zoomed_height =
draw_tile.params.size.y * zoom.
y;
882 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
884 else if (zoomed_width -
draw_tile.params.size.x > 0.5f ||
885 zoomed_height -
draw_tile.params.size.y > 0.5f) {
886 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
889 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
892 glVertexAttribPointer(
893 texcoord_attribute, 2, GL_FLOAT, GL_FALSE, 4 *
sizeof(
float), (
const GLvoid *)0);
894 glVertexAttribPointer(position_attribute,
899 (
const GLvoid *)(
sizeof(
float) * 2));
901 glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
952 glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
954 glActiveTexture(GL_TEXTURE0);
959 GLuint vertex_array_object;
960 glGenVertexArrays(1, &vertex_array_object);
961 glBindVertexArray(vertex_array_object);
965 const int texcoord_attribute =
display_shader_->get_tex_coord_attrib_location();
966 const int position_attribute =
display_shader_->get_position_attrib_location();
968 glEnableVertexAttribArray(texcoord_attribute);
969 glEnableVertexAttribArray(position_attribute);
971 if (
tiles_->current_tile.need_update_texture_pixels) {
973 tiles_->current_tile.need_update_texture_pixels =
false;
979 tiles_->current_tile.tile,
980 tiles_->gl_vertex_buffer);
988 glBindTexture(GL_TEXTURE_2D, 0);
989 glBindVertexArray(0);
990 glBindBuffer(GL_ARRAY_BUFFER, 0);
992 glDeleteVertexArrays(1, &vertex_array_object);
1029 LOG(ERROR) <<
"Error creating OpenGL context.";
1080 tiles_->current_tile.gl_resources_destroy();
1081 tiles_->finished_tiles.gl_resources_destroy_and_clear();
1082 tiles_->gl_resources_destroy();
_GL_VOID GLfloat value _GL_VOID_RET _GL_VOID const GLuint GLboolean *residences _GL_BOOL_RET _GL_VOID GLsizei height
_GL_VOID GLfloat value _GL_VOID_RET _GL_VOID const GLuint GLboolean *residences _GL_BOOL_RET _GL_VOID GLsizei GLfloat GLfloat GLfloat GLfloat const GLubyte *bitmap _GL_VOID_RET _GL_VOID GLenum const void *lists _GL_VOID_RET _GL_VOID const GLdouble *equation _GL_VOID_RET _GL_VOID GLdouble GLdouble blue _GL_VOID_RET _GL_VOID GLfloat GLfloat blue _GL_VOID_RET _GL_VOID GLint GLint blue _GL_VOID_RET _GL_VOID GLshort GLshort blue _GL_VOID_RET _GL_VOID GLubyte GLubyte blue _GL_VOID_RET _GL_VOID GLuint GLuint blue _GL_VOID_RET _GL_VOID GLushort GLushort blue _GL_VOID_RET _GL_VOID GLbyte GLbyte GLbyte alpha _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble alpha _GL_VOID_RET _GL_VOID GLfloat GLfloat GLfloat alpha _GL_VOID_RET _GL_VOID GLint GLint GLint alpha _GL_VOID_RET _GL_VOID GLshort GLshort GLshort alpha _GL_VOID_RET _GL_VOID GLubyte GLubyte GLubyte alpha _GL_VOID_RET _GL_VOID GLuint GLuint GLuint alpha _GL_VOID_RET _GL_VOID GLushort GLushort GLushort alpha _GL_VOID_RET _GL_VOID GLenum mode _GL_VOID_RET _GL_VOID GLint y
_GL_VOID GLfloat value _GL_VOID_RET _GL_VOID const GLuint GLboolean *residences _GL_BOOL_RET _GL_VOID GLsizei GLfloat GLfloat GLfloat GLfloat const GLubyte *bitmap _GL_VOID_RET _GL_VOID GLenum type
_GL_VOID GLfloat value _GL_VOID_RET _GL_VOID const GLuint GLboolean *residences _GL_BOOL_RET _GL_VOID GLsizei GLfloat GLfloat GLfloat GLfloat const GLubyte *bitmap _GL_VOID_RET _GL_VOID GLenum const void *lists _GL_VOID_RET _GL_VOID const GLdouble *equation _GL_VOID_RET _GL_VOID GLdouble GLdouble blue _GL_VOID_RET _GL_VOID GLfloat GLfloat blue _GL_VOID_RET _GL_VOID GLint GLint blue _GL_VOID_RET _GL_VOID GLshort GLshort blue _GL_VOID_RET _GL_VOID GLubyte GLubyte blue _GL_VOID_RET _GL_VOID GLuint GLuint blue _GL_VOID_RET _GL_VOID GLushort GLushort blue _GL_VOID_RET _GL_VOID GLbyte GLbyte GLbyte alpha _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble alpha _GL_VOID_RET _GL_VOID GLfloat GLfloat GLfloat alpha _GL_VOID_RET _GL_VOID GLint GLint GLint alpha _GL_VOID_RET _GL_VOID GLshort GLshort GLshort alpha _GL_VOID_RET _GL_VOID GLubyte GLubyte GLubyte alpha _GL_VOID_RET _GL_VOID GLuint GLuint GLuint alpha _GL_VOID_RET _GL_VOID GLushort GLushort GLushort alpha _GL_VOID_RET _GL_VOID GLenum mode _GL_VOID_RET _GL_VOID GLint GLsizei width
struct RenderEngine RenderEngine
static void vertex_buffer_update(const DisplayDriver::Params ¶ms)
static int compile_fallback_shader(void)
bool DRW_opengl_context_release()
void WM_opengl_context_dispose(void *gl_context)
static void update_tile_texture_pixels(const DrawTileAndPBO &tile)
void RE_engine_render_context_enable(struct RenderEngine *engine)
void WM_opengl_context_activate(void *gl_context)
void RE_engine_render_context_disable(struct RenderEngine *engine)
static void draw_tile(const float2 &zoom, const int texcoord_attribute, const int position_attribute, const DrawTile &draw_tile, const uint gl_vertex_buffer)
static const char * FALLBACK_VERTEX_SHADER
void WM_opengl_context_release(void *context)
void DRW_opengl_context_activate(bool drw_state)
bool RE_engine_has_render_context(struct RenderEngine *engine)
static const char * FALLBACK_FRAGMENT_SHADER
static void shader_print_errors(const char *task, const char *log, const char *code)
void * WM_opengl_context_create()
BlenderDisplayDriver(BL::RenderEngine &b_engine, BL::Scene &b_scene)
virtual half4 * map_texture_buffer() override
virtual void unmap_texture_buffer() override
virtual void clear() override
virtual bool update_begin(const Params ¶ms, int texture_width, int texture_height) override
void gl_resources_destroy()
std::atomic< bool > need_clear_
virtual void graphics_interop_activate() override
virtual GraphicsInterop graphics_interop_get() override
thread_mutex gl_context_mutex_
virtual void draw(const Params ¶ms) override
void gl_context_dispose()
void set_zoom(float zoom_x, float zoom_y)
virtual void flush() override
virtual void update_end() override
unique_ptr< Tiles > tiles_
unique_ptr< BlenderDisplayShader > display_shader_
virtual void graphics_interop_deactivate() override
BL::RenderEngine b_engine_
virtual void next_tile_begin() override
void gl_context_disable()
virtual int get_position_attrib_location()
static unique_ptr< BlenderDisplayShader > create(BL::RenderEngine &b_engine, BL::Scene &b_scene)
int tex_coord_attribute_location_
static constexpr const char * tex_coord_attribute_name
static constexpr const char * position_attribute_name
int position_attribute_location_
virtual uint get_shader_program()=0
virtual int get_tex_coord_attrib_location()
virtual void unbind() override
virtual void bind(int width, int height) override
BL::RenderEngine b_engine_
BlenderDisplaySpaceShader(BL::RenderEngine &b_engine, BL::Scene &b_scene)
virtual uint get_shader_program() override
virtual void bind(int width, int height) override
virtual void unbind() override
virtual uint get_shader_program() override
bool shader_compile_attempted_
void create_shader_if_needed()
int image_texture_location_
bool need_update_texture_pixels
bool gl_resources_ensure()
GLPixelBufferObject buffer_object
void gl_resources_destroy()
bool gl_resources_ensure()
DrawTile(const DrawTile &other)=delete
DrawTile & operator=(const DrawTile &other)=delete
void gl_resources_destroy()
DrawTile(DrawTile &&other) noexcept=default
DrawTile & operator=(DrawTile &&other)=default
bool ready_to_draw() const
BlenderDisplayDriver::Params params
void gl_resources_destroy()
GLPixelBufferObject & operator=(GLPixelBufferObject &other)=delete
GLPixelBufferObject(GLPixelBufferObject &&other) noexcept
GLPixelBufferObject(const GLPixelBufferObject &other)=delete
GLPixelBufferObject()=default
bool gl_resources_ensure()
static std::atomic< int > num_used
GLPixelBufferObject & operator=(GLPixelBufferObject &&other)
GLTexture & operator=(GLTexture &&other)
GLTexture(const GLTexture &other)=delete
GLTexture & operator=(GLTexture &other)=delete
static std::atomic< int > num_used
bool gl_resources_ensure()
GLTexture(GLTexture &&other) noexcept
void gl_resources_destroy()
#define CCL_NAMESPACE_END
ccl_global const KernelWorkTile * tile
#define DCHECK(expression)
#define VLOG_DEVICE_STATS
ccl_device_inline float3 log(float3 v)
std::unique_ptr< IDProperty, IDPropertyDeleter > create(StringRefNull prop_name, int32_t value)
Allocate a new IDProperty of type IDP_INT, set its name and value.
struct blender::compositor::@179::@181 task
T length(const vec_base< T, Size > &a)
void gl_resources_destroy()
DrawTileAndPBO current_tile
struct BlenderDisplayDriver::Tiles::@1227 finished_tiles
bool gl_resources_ensure()