Rendering: update_result() is very slow

Hi,

A little bit stuck here…

When you render something with Cycles, the image refresh / new pixels are drawn almost instantly, with very little lag.

I am trying to implement a progressive renderer through Python (bpy.types.RenderEngine) and whenever I call self.update_result(result) it takes about 4-5 seconds to update the render image…

I have been following this: https://docs.blender.org/api/2.79/bpy.types.RenderEngine.html however that does all the rendering and then finalizes by doing self.end_result(result).

Is there any good example of implementing a progressive rendering engine through this interface?

The code for the rendering loop is below. There is an adjustment to the order of the rendered rows, as these seem to be upside down, but that part (“wrangling”) doesn’t take as long as the “updating” part.

Any help would be very much appreciated!!

        raw_buffer = float_buffer.get_data_pointer()
        shape = int(self.resolution_y * self.resolution_x)

        pixels = [[0,0,0,0]] * shape

        result = self.begin_result(0, 0, self.resolution_x, self.resolution_y)
        layer = result.layers[0].passes["Combined"]

        print("Entering rendering loop...")

        while self.test_break() is False:
            # Tonemapping
            print("Pass {}".format(current_pass))
            start = time.time()

            self.renderer.Poll()
            tone_mapper.TonemapBlocking()

            end = time.time()
            print ("   tonemapping: {}".format(end-start))

            # Wrangling
            start = time.time()
            
            index = 0
            pi = 0
            
            for i in reversed(range(self.resolution_y)):
                for j in range(self.resolution_x):
                    index = (i * self.resolution_x + j) * 4
                    pixels[pi] = [raw_buffer[index] * scale, raw_buffer[index + 1] * scale, raw_buffer[index + 2] * scale, raw_buffer[index + 3]]
                    pi += 1

            end = time.time()
            print ("     wrangling: {}".format(end-start))

            # Updating
            start = time.time()
            layer.rect = pixels
            self.update_result(result)
            self.update_stats("SPP: %.2f" % self.renderer.samples_per_pixel, "Num. passes: %i" % current_pass)

            end = time.time()
            print ("      updating: {}".format(end-start))

            if self.renderer.samples_per_pixel > halt_samples:
                break
                
            current_pass += 1         

        self.end_result(result)
        self.renderer.Stop()