0
0
mirror of https://github.com/mpv-player/mpv.git synced 2024-09-20 20:03:10 +02:00
mpv/video/out/gpu/error_diffusion.h
Bin Jin ca2f193671 vo_gpu: implement error diffusion for dithering
This is a straightforward parallel implementation of error diffusion
algorithms in compute shader. Basically we use single work group with
maximal possible size to process the whole image. After a shift
mapping we are able to process all pixels column by column.

A large ring buffer are allocated in shared memory to speed things up.
However the size of required shared memory depends linearly on the
height of video window (or screen height in fullscreen mode). In case
there is no enough shared memory, it will fallback to `--dither=fruit`.

The maximal allowed work group size is hardcoded as 1024. Ideally we
could query `GL_MAX_COMPUTE_WORK_GROUP_INVOCATIONS`. But for whatever
reason, it seems most high end card from nvidia and amd support only
the minimal required value, so I guess we can stick to it for now.
2019-06-16 11:19:44 +02:00

49 lines
1.8 KiB
C

/*
* This file is part of mpv.
*
* mpv is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* mpv is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with mpv. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef MP_GL_ERROR_DIFFUSION
#define MP_GL_ERROR_DIFFUSION
#include "shader_cache.h"
// defines the border of all error diffusion kernels
#define EF_MIN_DELTA_X (-2)
#define EF_MAX_DELTA_X (2)
#define EF_MAX_DELTA_Y (2)
struct error_diffusion_kernel {
const char *name;
// The minimum value such that a (y, x) -> (y, x + y * shift) mapping will
// make all error pushing operations affect next column (and after it) only.
int shift;
// The diffusion factor for (y, x) is pattern[y][x - EF_MIN_DELTA_X] / divisor.
int pattern[EF_MAX_DELTA_Y + 1][EF_MAX_DELTA_X - EF_MIN_DELTA_X + 1];
int divisor;
};
extern const struct error_diffusion_kernel mp_error_diffusion_kernels[];
const struct error_diffusion_kernel *mp_find_error_diffusion_kernel(const char *name);
int mp_ef_compute_shared_memory_size(const struct error_diffusion_kernel *k, int height);
void pass_error_diffusion(struct gl_shader_cache *sc,
const struct error_diffusion_kernel *k,
int tex, int width, int height, int depth, int block_size);
#endif /* MP_GL_ERROR_DIFFUSION */