/* * Copyright (C) 2017 Kovid Goyal * * Distributed under terms of the GPL3 license. */ #pragma once #include "data-types.h" #include "monotonic.h" typedef struct { unsigned char action, transmission_type, compressed, delete_action; uint32_t format, more, id, image_number, data_sz, data_offset, placement_id, quiet; uint32_t width, height, x_offset, y_offset; union { uint32_t cursor_movement, compose_mode; }; union { uint32_t cell_x_offset, blend_mode; }; union { uint32_t cell_y_offset, bgcolor; }; union { uint32_t data_width, animation_state; }; union { uint32_t data_height, loop_count; }; union { uint32_t num_lines, frame_number; }; union { uint32_t num_cells, other_frame_number; }; union { int32_t z_index, gap; }; size_t payload_sz; } GraphicsCommand; typedef struct { float left, top, right, bottom; } ImageRect; typedef struct { uint32_t src_width, src_height, src_x, src_y; uint32_t cell_x_offset, cell_y_offset, num_cols, num_rows, effective_num_rows, effective_num_cols; int32_t z_index; int32_t start_row, start_column; uint32_t client_id; ImageRect src_rect; } ImageRef; typedef struct { uint32_t gap, id, width, height, x, y, base_frame_id, bgcolor; bool is_opaque, is_4byte_aligned, alpha_blend; } Frame; typedef enum { ANIMATION_STOPPED = 0, ANIMATION_LOADING = 1, ANIMATION_RUNNING = 2} AnimationState; typedef struct { uint32_t texture_id, client_id, client_number, width, height; id_type internal_id; bool root_frame_data_loaded; ImageRef *refs; Frame *extra_frames, root_frame; uint32_t current_frame_index, frame_id_counter; uint64_t animation_duration; size_t refcnt, refcap, extra_framecnt; monotonic_t atime; size_t used_storage; bool is_drawn; AnimationState animation_state; uint32_t max_loops, current_loop; monotonic_t current_frame_shown_at; } Image; typedef struct { uint32_t texture_id; unsigned int height, width; uint8_t* bitmap; uint32_t refcnt; } BackgroundImage; typedef struct { float vertices[16]; uint32_t texture_id, group_count; int z_index; id_type image_id; } ImageRenderData; typedef struct { id_type image_id; uint32_t frame_id; } ImageAndFrame; typedef struct { uint8_t *buf; size_t buf_capacity, buf_used; uint8_t *mapped_file; size_t mapped_file_sz; size_t data_sz; uint8_t *data; bool is_4byte_aligned; bool is_opaque, loading_completed_successfully; uint32_t width, height; GraphicsCommand start_command; ImageAndFrame loading_for; } LoadData; typedef struct { PyObject_HEAD size_t image_count, images_capacity, storage_limit; LoadData currently_loading; Image *images; size_t count, capacity; ImageRenderData *render_data; bool layers_dirty; // 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. size_t num_of_below_refs, num_of_negative_refs, num_of_positive_refs; unsigned int last_scrolled_by; size_t used_storage; PyObject *disk_cache; bool has_images_needing_animation, context_made_current_for_this_command; id_type window_id; } GraphicsManager; typedef struct { int32_t amt, limit; index_type margin_top, margin_bottom; bool has_margins; } ScrollData; static inline float gl_size(const unsigned int sz, const unsigned int viewport_size) { // convert pixel sz to OpenGL co-ordinate system. const float px = 2.f / viewport_size; return px * sz; } static inline float clamp_position_to_nearest_pixel(float pos, const unsigned int viewport_size) { // clamp the specified opengl position to the nearest pixel const float px = 2.f / viewport_size; const float distance = pos + 1.f; const float num_of_pixels = roundf(distance / px); return -1.f + num_of_pixels * px; } static inline float gl_pos_x(const unsigned int px_from_left_margin, const unsigned int viewport_size) { const float px = 2.f / viewport_size; return -1.f + px_from_left_margin * px; } static inline float gl_pos_y(const unsigned int px_from_top_margin, const unsigned int viewport_size) { const float px = 2.f / viewport_size; return 1.f - px_from_top_margin * px; } GraphicsManager* grman_alloc(void); void grman_clear(GraphicsManager*, bool, CellPixelSize fg); const char* grman_handle_command(GraphicsManager *self, const GraphicsCommand *g, const uint8_t *payload, Cursor *c, bool *is_dirty, CellPixelSize fg); 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); void grman_scroll_images(GraphicsManager *self, const ScrollData*, CellPixelSize fg); void grman_resize(GraphicsManager*, index_type, index_type, index_type, index_type); void grman_rescale(GraphicsManager *self, CellPixelSize fg); void gpu_data_for_image(ImageRenderData *ans, float left, float top, float right, float bottom); void gpu_data_for_centered_image(ImageRenderData *ans, unsigned int screen_width_px, unsigned int screen_height_px, unsigned int width, unsigned int height); bool png_path_to_bitmap(const char *path, uint8_t** data, unsigned int* width, unsigned int* height, size_t* sz); bool scan_active_animations(GraphicsManager *self, const monotonic_t now, monotonic_t *minimum_gap, bool os_window_context_set);