The OffscreenEffect class is meant to be used to implement Effect
sub-classes that create an offscreen framebuffer and redirect the
actor's paint sequence there. The OffscreenEffect is useful for
effects using fragment shaders.
Any shader-based effect being applied to an actor through an offscreen
buffer should be used before painting the resulting target material and
not for every actor. This means that doing:
pre_paint: cogl_program_use(program)
set up offscreen buffer
paint: [ actors ] → offscreen buffer → target material
post_paint: paint target material
cogl_program_use(null)
Is not correct. Unfortunately, we cannot really do:
post_paint: cogl_program_use(program)
paint target material
cogl_program_use(null)
Because the OffscreenEffect::post_paint() implementation also pops the
offscreen buffer and re-instates the previous framebuffer:
post_paint: cogl_program_use(program)
change frame buffer ← ouch!
paint target material
cogl_program_use(null)
One way to fix it is to allow using the shader right before painting
the target material - which means adding a new virtual inside the
OffscreenEffect class vtable in additions to the ones defined by the
parent Effect class.
The newly-added paint_target() virtual allows the correct sequence of
actions by adding an entry point for sub-classes to wrap the "paint
target material" operation with custom code, in order to implement the
case above correctly as:
post_paint: change frame buffer
cogl_program_use(program)
paint target material
cogl_program_use(null)
The added upside is that sub-classes of OffscreenEffect involving
shaders really just need to override the prepare() and paint_target()
virtuals, since the pre_paint() and post_paint() do all that's needed.