1 /*
2  * Copyright (C) 2017 Kovid Goyal <kovid at kovidgoyal.net>
3  *
4  * Distributed under terms of the GPL3 license.
5  */
6 
7 #pragma once
8 #include "data-types.h"
9 #include "monotonic.h"
10 
11 typedef struct {
12     unsigned char action, transmission_type, compressed, delete_action;
13     uint32_t format, more, id, image_number, data_sz, data_offset, placement_id, quiet;
14     uint32_t width, height, x_offset, y_offset;
15     union { uint32_t cursor_movement, compose_mode; };
16     union { uint32_t cell_x_offset, blend_mode; };
17     union { uint32_t cell_y_offset, bgcolor; };
18     union { uint32_t data_width, animation_state; };
19     union { uint32_t data_height, loop_count; };
20     union { uint32_t num_lines, frame_number; };
21     union { uint32_t num_cells, other_frame_number; };
22     union { int32_t z_index, gap; };
23     size_t payload_sz;
24 } GraphicsCommand;
25 
26 typedef struct {
27     float left, top, right, bottom;
28 } ImageRect;
29 
30 typedef struct {
31     uint32_t src_width, src_height, src_x, src_y;
32     uint32_t cell_x_offset, cell_y_offset, num_cols, num_rows, effective_num_rows, effective_num_cols;
33     int32_t z_index;
34     int32_t start_row, start_column;
35     uint32_t client_id;
36     ImageRect src_rect;
37 } ImageRef;
38 
39 typedef struct {
40     uint32_t gap, id, width, height, x, y, base_frame_id, bgcolor;
41     bool is_opaque, is_4byte_aligned, alpha_blend;
42 } Frame;
43 
44 typedef enum { ANIMATION_STOPPED = 0, ANIMATION_LOADING = 1, ANIMATION_RUNNING = 2} AnimationState;
45 
46 typedef struct {
47     uint32_t texture_id, client_id, client_number, width, height;
48     id_type internal_id;
49 
50     bool root_frame_data_loaded;
51     ImageRef *refs;
52     Frame *extra_frames, root_frame;
53     uint32_t current_frame_index, frame_id_counter;
54     uint64_t animation_duration;
55     size_t refcnt, refcap, extra_framecnt;
56     monotonic_t atime;
57     size_t used_storage;
58     bool is_drawn;
59     AnimationState animation_state;
60     uint32_t max_loops, current_loop;
61     monotonic_t current_frame_shown_at;
62 } Image;
63 
64 typedef struct {
65     uint32_t texture_id;
66     unsigned int height, width;
67     uint8_t* bitmap;
68     uint32_t refcnt;
69 } BackgroundImage;
70 
71 typedef struct {
72     float vertices[16];
73     uint32_t texture_id, group_count;
74     int z_index;
75     id_type image_id;
76 } ImageRenderData;
77 
78 typedef struct {
79     id_type image_id;
80     uint32_t frame_id;
81 } ImageAndFrame;
82 
83 typedef struct {
84     uint8_t *buf;
85     size_t buf_capacity, buf_used;
86 
87     uint8_t *mapped_file;
88     size_t mapped_file_sz;
89 
90     size_t data_sz;
91     uint8_t *data;
92     bool is_4byte_aligned;
93     bool is_opaque, loading_completed_successfully;
94     uint32_t width, height;
95     GraphicsCommand start_command;
96     ImageAndFrame loading_for;
97 } LoadData;
98 
99 typedef struct {
100     PyObject_HEAD
101 
102     size_t image_count, images_capacity, storage_limit;
103     LoadData currently_loading;
104     Image *images;
105     size_t count, capacity;
106     ImageRenderData *render_data;
107     bool layers_dirty;
108     // The number of images below MIN_ZINDEX / 2, then the number of refs between MIN_ZINDEX / 2 and -1 inclusive, then the number of refs above 0 inclusive.
109     size_t num_of_below_refs, num_of_negative_refs, num_of_positive_refs;
110     unsigned int last_scrolled_by;
111     size_t used_storage;
112     PyObject *disk_cache;
113     bool has_images_needing_animation, context_made_current_for_this_command;
114     id_type window_id;
115 } GraphicsManager;
116 
117 
118 typedef struct {
119     int32_t amt, limit;
120     index_type margin_top, margin_bottom;
121     bool has_margins;
122 } ScrollData;
123 
124 GraphicsManager* grman_alloc(void);
125 void grman_clear(GraphicsManager*, bool, CellPixelSize fg);
126 const char* grman_handle_command(GraphicsManager *self, const GraphicsCommand *g, const uint8_t *payload, Cursor *c, bool *is_dirty, CellPixelSize fg);
127 bool grman_update_layers(GraphicsManager *self, unsigned int scrolled_by, float screen_left, float screen_top, float dx, float dy, unsigned int num_cols, unsigned int num_rows, CellPixelSize);
128 void grman_scroll_images(GraphicsManager *self, const ScrollData*, CellPixelSize fg);
129 void grman_resize(GraphicsManager*, index_type, index_type, index_type, index_type);
130 void grman_rescale(GraphicsManager *self, CellPixelSize fg);
131 void gpu_data_for_centered_image(ImageRenderData *ans, unsigned int screen_width_px, unsigned int screen_height_px, unsigned int width, unsigned int height);
132 bool png_path_to_bitmap(const char *path, uint8_t** data, unsigned int* width, unsigned int* height, size_t* sz);
133 bool scan_active_animations(GraphicsManager *self, const monotonic_t now, monotonic_t *minimum_gap, bool os_window_context_set);
134