blob: c1c2b9165f3adcf0da7fe29fe37b9c1d28d25d98 [file] [log] [blame]
#ifndef ANDROID_DVR_GRAPHICS_BLUR_H_
#define ANDROID_DVR_GRAPHICS_BLUR_H_
#include <EGL/egl.h>
#include <EGL/eglext.h>
#include <GLES2/gl2.h>
#include <algorithm>
#include <vector>
#include <private/dvr/ring_buffer.h>
namespace android {
namespace dvr {
class Blur {
public:
// Construct a blur kernel for GL that works on source textures of the given
// size. The given source_texture is configured for linear filtering.
// |source_texture_target| is for |source_texture| while
// |target_texture_target| is used for all the intermediate and output
// buffers.
// |num_blur_outputs| determines how many blurs this instance can be used for
// in a single frame.
Blur(int w, int h, GLuint source_texture, GLint source_texture_target,
GLint target_texture_target, bool is_external, EGLDisplay display,
int num_blur_outputs);
~Blur();
// Place all output textures back into the FBO pool for a new frame.
// Call this at the start of each frame before doing one or more blurs.
void StartFrame();
// Draw a multipass blur from the given source_texture. The resulting texture
// is returned. The given source_texture is configured for linear filtering.
// A segfault will occur if the application calls DrawBlur more times than
// |num_blur_outputs| without calling StartFrame.
// It is up to the calling code to change the framebuffer after this method.
GLuint DrawBlur(GLuint source_texture);
float width() const { return width_; }
float height() const { return height_; }
float scale() const { return scale_; }
// Set the scale of the blur, usually between 0 and 1. This is only useful for
// animation.
// At the steady state, the scale should be set to 1. To change the steady
// state blur appearance, the kernel patterns in DrawBlur should be modified
// instead of using scale.
void set_scale(float scale) { scale_ = scale; }
// Animate the blur by |delta|. Clamp the result between |low| and |high|.
// Recommended range is between 0 and 1, but other values will also work.
void animate(float delta, float low, float high) {
scale_ += delta;
scale_ = std::min(high, std::max(low, scale_));
}
private:
struct Fbo {
Fbo() : fbo(0), renderbuffer(0), texture(0), egl_image(0) {}
GLuint fbo;
GLuint renderbuffer;
GLuint texture;
EGLImageKHR egl_image;
};
Fbo CreateFbo(int w, int h, GLuint source_texture, GLint tex_target,
bool is_external);
// EGL display for when target texture format is EGL image.
EGLDisplay display_;
GLint target_texture_target_;
int width_;
int height_;
Fbo source_fbo_;
Fbo fbo_half_;
std::vector<Fbo> fbo_q_;
RingBuffer<Fbo> fbo_q_free_;
float scale_;
};
} // namespace dvr
} // namespace android
#endif // ANDROID_DVR_GRAPHICS_BLUR_H_