From 74518b28267e9b18199212fbaa3c689fa018d20c Mon Sep 17 00:00:00 2001 From: Sergey Sharybin Date: Wed, 26 Mar 2014 14:57:30 +0600 Subject: [PATCH] Fix T39420: Cycles viewport/preview flickers, when moving mouse across editors Issue was caused by the wrong usage of OCIO GLSL binding API. To make it work properly on pre-GLSL-1.3 drivers shader is to be enabled after the texture is binded to the opengl context. Otherwise it wouldn't know the proper texture size. This is actually a regression in 2.70 and to be ported to 'a'. --- intern/cycles/blender/blender_session.cpp | 14 ++++++-------- intern/cycles/device/device.cpp | 11 ++++++++++- intern/cycles/device/device.h | 8 +++++++- intern/cycles/device/device_cuda.cpp | 13 +++++++++++-- intern/cycles/device/device_multi.cpp | 5 +++-- intern/cycles/render/buffers.cpp | 4 ++-- intern/cycles/render/buffers.h | 3 ++- intern/cycles/render/session.cpp | 14 +++++++------- intern/cycles/render/session.h | 6 +++--- 9 files changed, 51 insertions(+), 27 deletions(-) diff --git a/intern/cycles/blender/blender_session.cpp b/intern/cycles/blender/blender_session.cpp index ef578493901..09e7472caf2 100644 --- a/intern/cycles/blender/blender_session.cpp +++ b/intern/cycles/blender/blender_session.cpp @@ -592,16 +592,14 @@ bool BlenderSession::draw(int w, int h) /* draw */ BufferParams buffer_params = BlenderSync::get_buffer_params(b_render, b_scene, b_v3d, b_rv3d, scene->camera, width, height); + DeviceDrawParams draw_params; - if(session->params.display_buffer_linear) - b_engine.bind_display_space_shader(b_scene); + if(session->params.display_buffer_linear) { + draw_params.bind_display_space_shader_cb = function_bind(&BL::RenderEngine::bind_display_space_shader, &b_engine, b_scene); + draw_params.unbind_display_space_shader_cb = function_bind(&BL::RenderEngine::unbind_display_space_shader, &b_engine); + } - bool draw_ok = !session->draw(buffer_params); - - if(session->params.display_buffer_linear) - b_engine.unbind_display_space_shader(); - - return draw_ok; + return !session->draw(buffer_params, draw_params); } void BlenderSession::get_status(string& status, string& substatus) diff --git a/intern/cycles/device/device.cpp b/intern/cycles/device/device.cpp index a3264f0c516..7fd1b79f6bc 100644 --- a/intern/cycles/device/device.cpp +++ b/intern/cycles/device/device.cpp @@ -53,7 +53,8 @@ void Device::pixels_free(device_memory& mem) mem_free(mem); } -void Device::draw_pixels(device_memory& rgba, int y, int w, int h, int dy, int width, int height, bool transparent) +void Device::draw_pixels(device_memory& rgba, int y, int w, int h, int dy, int width, int height, bool transparent, + const DeviceDrawParams &draw_params) { pixels_copy_from(rgba, y, w, h); @@ -80,6 +81,10 @@ void Device::draw_pixels(device_memory& rgba, int y, int w, int h, int dy, int w glEnable(GL_TEXTURE_2D); + if(draw_params.bind_display_space_shader_cb) { + draw_params.bind_display_space_shader_cb(); + } + glPushMatrix(); glTranslatef(0.0f, (float)dy, 0.0f); @@ -98,6 +103,10 @@ void Device::draw_pixels(device_memory& rgba, int y, int w, int h, int dy, int w glPopMatrix(); + if(draw_params.unbind_display_space_shader_cb) { + draw_params.unbind_display_space_shader_cb(); + } + glBindTexture(GL_TEXTURE_2D, 0); glDisable(GL_TEXTURE_2D); glDeleteTextures(1, &texid); diff --git a/intern/cycles/device/device.h b/intern/cycles/device/device.h index f94075f9aa5..cbabcb1e20e 100644 --- a/intern/cycles/device/device.h +++ b/intern/cycles/device/device.h @@ -69,6 +69,11 @@ public: /* Device */ +struct DeviceDrawParams { + boost::function bind_display_space_shader_cb; + boost::function unbind_display_space_shader_cb; +}; + class Device { protected: Device(DeviceInfo& info_, Stats &stats_, bool background) : background(background), info(info_), stats(stats_) {} @@ -121,7 +126,8 @@ public: /* opengl drawing */ virtual void draw_pixels(device_memory& mem, int y, int w, int h, - int dy, int width, int height, bool transparent); + int dy, int width, int height, bool transparent, + const DeviceDrawParams &draw_params); #ifdef WITH_NETWORK /* networking */ diff --git a/intern/cycles/device/device_cuda.cpp b/intern/cycles/device/device_cuda.cpp index f3f6344521b..25001419d39 100644 --- a/intern/cycles/device/device_cuda.cpp +++ b/intern/cycles/device/device_cuda.cpp @@ -908,7 +908,8 @@ public: } } - void draw_pixels(device_memory& mem, int y, int w, int h, int dy, int width, int height, bool transparent) + void draw_pixels(device_memory& mem, int y, int w, int h, int dy, int width, int height, bool transparent, + const DeviceDrawParams &draw_params) { if(!background) { PixelMem pmem = pixel_mem_map[mem.device_pointer]; @@ -941,6 +942,10 @@ public: glColor3f(1.0f, 1.0f, 1.0f); + if(draw_params.bind_display_space_shader_cb) { + draw_params.bind_display_space_shader_cb(); + } + glPushMatrix(); glTranslatef(0.0f, (float)dy, 0.0f); @@ -959,6 +964,10 @@ public: glPopMatrix(); + if(draw_params.unbind_display_space_shader_cb) { + draw_params.unbind_display_space_shader_cb(); + } + if(transparent) glDisable(GL_BLEND); @@ -970,7 +979,7 @@ public: return; } - Device::draw_pixels(mem, y, w, h, dy, width, height, transparent); + Device::draw_pixels(mem, y, w, h, dy, width, height, transparent, draw_params); } void thread_run(DeviceTask *task) diff --git a/intern/cycles/device/device_multi.cpp b/intern/cycles/device/device_multi.cpp index 1e9367c845a..59bbf3b9d5a 100644 --- a/intern/cycles/device/device_multi.cpp +++ b/intern/cycles/device/device_multi.cpp @@ -233,7 +233,8 @@ public: mem.device_pointer = tmp; } - void draw_pixels(device_memory& rgba, int y, int w, int h, int dy, int width, int height, bool transparent) + void draw_pixels(device_memory& rgba, int y, int w, int h, int dy, int width, int height, bool transparent, + const DeviceDrawParams &draw_params) { device_ptr tmp = rgba.device_pointer; int i = 0, sub_h = h/devices.size(); @@ -247,7 +248,7 @@ public: /* adjust math for w/width */ rgba.device_pointer = sub.ptr_map[tmp]; - sub.device->draw_pixels(rgba, sy, w, sh, sdy, width, sheight, transparent); + sub.device->draw_pixels(rgba, sy, w, sh, sdy, width, sheight, transparent, draw_params); i++; } diff --git a/intern/cycles/render/buffers.cpp b/intern/cycles/render/buffers.cpp index da1b7484b77..fc65922fc87 100644 --- a/intern/cycles/render/buffers.cpp +++ b/intern/cycles/render/buffers.cpp @@ -358,14 +358,14 @@ void DisplayBuffer::draw_set(int width, int height) draw_height = height; } -void DisplayBuffer::draw(Device *device) +void DisplayBuffer::draw(Device *device, const DeviceDrawParams& draw_params) { if(draw_width != 0 && draw_height != 0) { glPushMatrix(); glTranslatef(params.full_x, params.full_y, 0.0f); device_memory& rgba = rgba_data(); - device->draw_pixels(rgba, 0, draw_width, draw_height, 0, params.width, params.height, transparent); + device->draw_pixels(rgba, 0, draw_width, draw_height, 0, params.width, params.height, transparent, draw_params); glPopMatrix(); } diff --git a/intern/cycles/render/buffers.h b/intern/cycles/render/buffers.h index 81eaf41077f..020add6526a 100644 --- a/intern/cycles/render/buffers.h +++ b/intern/cycles/render/buffers.h @@ -31,6 +31,7 @@ CCL_NAMESPACE_BEGIN class Device; +class DeviceDrawParams; struct float4; /* Buffer Parameters @@ -114,7 +115,7 @@ public: void write(Device *device, const string& filename); void draw_set(int width, int height); - void draw(Device *device); + void draw(Device *device, const DeviceDrawParams& draw_params); bool draw_ready(); device_memory& rgba_data(); diff --git a/intern/cycles/render/session.cpp b/intern/cycles/render/session.cpp index 0805a685467..2b799972a97 100644 --- a/intern/cycles/render/session.cpp +++ b/intern/cycles/render/session.cpp @@ -151,7 +151,7 @@ void Session::reset_gpu(BufferParams& buffer_params, int samples) pause_cond.notify_all(); } -bool Session::draw_gpu(BufferParams& buffer_params) +bool Session::draw_gpu(BufferParams& buffer_params, DeviceDrawParams& draw_params) { /* block for buffer access */ thread_scoped_lock display_lock(display_mutex); @@ -170,7 +170,7 @@ bool Session::draw_gpu(BufferParams& buffer_params) gpu_need_tonemap_cond.notify_all(); } - display->draw(device); + display->draw(device, draw_params); if(display_outdated && (time_dt() - reset_time) > params.text_timeout) return false; @@ -315,7 +315,7 @@ void Session::reset_cpu(BufferParams& buffer_params, int samples) pause_cond.notify_all(); } -bool Session::draw_cpu(BufferParams& buffer_params) +bool Session::draw_cpu(BufferParams& buffer_params, DeviceDrawParams& draw_params) { thread_scoped_lock display_lock(display_mutex); @@ -324,7 +324,7 @@ bool Session::draw_cpu(BufferParams& buffer_params) /* then verify the buffers have the expected size, so we don't * draw previous results in a resized window */ if(!buffer_params.modified(display->params)) { - display->draw(device); + display->draw(device, draw_params); if(display_outdated && (time_dt() - reset_time) > params.text_timeout) return false; @@ -624,12 +624,12 @@ void Session::run() progress.set_update(); } -bool Session::draw(BufferParams& buffer_params) +bool Session::draw(BufferParams& buffer_params, DeviceDrawParams &draw_params) { if(device_use_gl) - return draw_gpu(buffer_params); + return draw_gpu(buffer_params, draw_params); else - return draw_cpu(buffer_params); + return draw_cpu(buffer_params, draw_params); } void Session::reset_(BufferParams& buffer_params, int samples) diff --git a/intern/cycles/render/session.h b/intern/cycles/render/session.h index 1227edf81b6..e2a7076f250 100644 --- a/intern/cycles/render/session.h +++ b/intern/cycles/render/session.h @@ -128,7 +128,7 @@ public: ~Session(); void start(); - bool draw(BufferParams& params); + bool draw(BufferParams& params, DeviceDrawParams& draw_params); void wait(); bool ready_to_reset(); @@ -155,11 +155,11 @@ protected: void reset_(BufferParams& params, int samples); void run_cpu(); - bool draw_cpu(BufferParams& params); + bool draw_cpu(BufferParams& params, DeviceDrawParams& draw_params); void reset_cpu(BufferParams& params, int samples); void run_gpu(); - bool draw_gpu(BufferParams& params); + bool draw_gpu(BufferParams& params, DeviceDrawParams& draw_params); void reset_gpu(BufferParams& params, int samples); bool acquire_tile(Device *tile_device, RenderTile& tile);