spice/server/image-encoders.h
Frediano Ziglio 435daaffdb worker: RedCompressBuf optimization
Move large buffer field at the end of structure.
Due to the way machine address memory this usually can reduce code size
and make program sligthly faster.
Actually reduce size by 100 bytes.

Signed-off-by: Frediano Ziglio <fziglio@redhat.com>
Acked-by: Pavel Grunt <pgrunt@redhat.com>
2016-09-26 10:27:58 +01:00

218 lines
6.6 KiB
C

/* -*- Mode: C; c-basic-offset: 4; indent-tabs-mode: nil -*- */
/*
Copyright (C) 2009-2015 Red Hat, Inc.
This library 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.
This library 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 this library; if not, see <http://www.gnu.org/licenses/>.
*/
#ifndef IMAGE_ENCODERS_H_
#define IMAGE_ENCODERS_H_
#include <setjmp.h>
#include <common/quic.h>
#include <common/lz.h>
#include "stat.h"
#include "red-parse-qxl.h"
#include "glz-encoder.h"
#include "jpeg-encoder.h"
#ifdef USE_LZ4
#include "lz4-encoder.h"
#endif
#include "zlib-encoder.h"
struct RedClient;
typedef struct RedCompressBuf RedCompressBuf;
typedef struct ImageEncoders ImageEncoders;
typedef struct ImageEncoderSharedData ImageEncoderSharedData;
typedef struct GlzSharedDictionary GlzSharedDictionary;
typedef struct GlzImageRetention GlzImageRetention;
void image_encoder_shared_init(ImageEncoderSharedData *shared_data);
void image_encoder_shared_stat_reset(ImageEncoderSharedData *shared_data);
void image_encoder_shared_stat_print(const ImageEncoderSharedData *shared_data);
void image_encoders_init(ImageEncoders *enc, ImageEncoderSharedData *shared_data);
void image_encoders_free(ImageEncoders *enc);
int image_encoders_free_some_independent_glz_drawables(ImageEncoders *enc);
void image_encoders_free_glz_drawables(ImageEncoders *enc);
void image_encoders_free_glz_drawables_to_free(ImageEncoders* enc);
gboolean image_encoders_glz_create(ImageEncoders *enc, uint8_t id);
void image_encoders_glz_get_restore_data(ImageEncoders *enc,
uint8_t *out_id, GlzEncDictRestoreData *out_data);
gboolean image_encoders_glz_encode_lock(ImageEncoders *enc);
void image_encoders_glz_encode_unlock(ImageEncoders *enc);
void glz_retention_free_drawables(GlzImageRetention *ret);
void glz_retention_detach_drawables(GlzImageRetention *ret);
#define RED_COMPRESS_BUF_SIZE (1024 * 64)
struct RedCompressBuf {
RedCompressBuf *send_next;
/* This buffer provide space for compression algorithms.
* Some algorithms access the buffer as an array of 32 bit words
* so is defined to make sure is always aligned that way.
*/
union {
uint8_t bytes[RED_COMPRESS_BUF_SIZE];
uint32_t words[RED_COMPRESS_BUF_SIZE / 4];
} buf;
};
static inline void compress_buf_free(RedCompressBuf *buf)
{
g_free(buf);
}
gboolean image_encoders_get_glz_dictionary(ImageEncoders *enc,
struct RedClient *client,
uint8_t id, int window_size);
gboolean image_encoders_restore_glz_dictionary(ImageEncoders *enc,
struct RedClient *client,
uint8_t id,
GlzEncDictRestoreData *restore_data);
typedef struct {
RedCompressBuf *bufs_head;
RedCompressBuf *bufs_tail;
jmp_buf jmp_env;
union {
struct {
SpiceChunks *chunks;
int next;
int stride;
int reverse;
} lines_data;
struct {
RedCompressBuf* next;
int size_left;
} compressed_data; // for encoding data that was already compressed by another method
} u;
} EncoderData;
typedef struct {
QuicUsrContext usr;
EncoderData data;
} QuicData;
typedef struct {
LzUsrContext usr;
EncoderData data;
} LzData;
typedef struct {
JpegEncoderUsrContext usr;
EncoderData data;
} JpegData;
#ifdef USE_LZ4
typedef struct {
Lz4EncoderUsrContext usr;
EncoderData data;
} Lz4Data;
#endif
typedef struct {
ZlibEncoderUsrContext usr;
EncoderData data;
} ZlibData;
typedef struct {
GlzEncoderUsrContext usr;
EncoderData data;
} GlzData;
struct GlzImageRetention {
Ring ring;
};
static inline void glz_retention_init(GlzImageRetention *ret)
{
ring_init(&ret->ring);
}
struct ImageEncoderSharedData {
uint32_t glz_drawable_count;
stat_info_t off_stat;
stat_info_t lz_stat;
stat_info_t glz_stat;
stat_info_t quic_stat;
stat_info_t jpeg_stat;
stat_info_t zlib_glz_stat;
stat_info_t jpeg_alpha_stat;
stat_info_t lz4_stat;
};
struct ImageEncoders {
ImageEncoderSharedData *shared_data;
QuicData quic_data;
QuicContext *quic;
LzData lz_data;
LzContext *lz;
int jpeg_quality;
JpegData jpeg_data;
JpegEncoderContext *jpeg;
#ifdef USE_LZ4
Lz4Data lz4_data;
Lz4EncoderContext *lz4;
#endif
int zlib_level;
ZlibData zlib_data;
ZlibEncoder *zlib;
/* global lz encoding entities */
GlzSharedDictionary *glz_dict;
GlzEncoderContext *glz;
GlzData glz_data;
Ring glz_drawables; // all the living lz drawable, ordered by encoding time
Ring glz_drawables_inst_to_free; // list of instances to be freed
pthread_mutex_t glz_drawables_inst_to_free_lock;
};
typedef struct compress_send_data_t {
RedCompressBuf *comp_buf;
uint32_t comp_buf_size;
SpicePalette *lzplt_palette;
gboolean is_lossy;
} compress_send_data_t;
int image_encoders_compress_quic(ImageEncoders *enc, SpiceImage *dest,
SpiceBitmap *src, compress_send_data_t* o_comp_data);
int image_encoders_compress_lz(ImageEncoders *enc,
SpiceImage *dest, SpiceBitmap *src,
compress_send_data_t* o_comp_data);
int image_encoders_compress_jpeg(ImageEncoders *enc, SpiceImage *dest,
SpiceBitmap *src, compress_send_data_t* o_comp_data);
int image_encoders_compress_lz4(ImageEncoders *enc, SpiceImage *dest,
SpiceBitmap *src, compress_send_data_t* o_comp_data);
int image_encoders_compress_glz(ImageEncoders *enc,
SpiceImage *dest, SpiceBitmap *src,
RedDrawable *red_drawable,
GlzImageRetention *glz_retention,
compress_send_data_t* o_comp_data,
gboolean enable_zlib_glz_wrap);
#define RED_RELEASE_BUNCH_SIZE 64
#endif /* IMAGE_ENCODERS_H_ */