Welcome to mirror list, hosted at ThFree Co, Russian Federation.

image_instance_data.hh « image « engines « draw « blender « source - git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
blob: f8f20fbe178918344c851ba9353c906ea75319d5 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
/*
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License
 * as published by the Free Software Foundation; either version 2
 * of the License, or (at your option) any later version.
 *
 * This program 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 General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software Foundation,
 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
 *
 * Copyright 2021, Blender Foundation.
 */

/** \file
 * \ingroup draw_engine
 */

#pragma once

#include "image_batches.hh"
#include "image_buffer_cache.hh"
#include "image_partial_updater.hh"
#include "image_private.hh"
#include "image_shader_params.hh"
#include "image_texture_info.hh"
#include "image_usage.hh"
#include "image_wrappers.hh"

#include "DRW_render.h"

/**
 * \brief max allowed textures to use by the ScreenSpaceDrawingMode.
 *
 * 4 textures are used to reduce uploading screen space textures when translating the image.
 */
constexpr int SCREEN_SPACE_DRAWING_MODE_TEXTURE_LEN = 1;

struct IMAGE_InstanceData {
  struct Image *image;
  /** Usage data of the previous time, to identify changes that require a full update. */
  ImageUsage last_usage;

  PartialImageUpdater partial_update;

  struct DRWView *view;
  ShaderParameters sh_params;
  struct {
    /**
     * \brief should we perform tiled drawing (wrap repeat).
     *
     * Option is true when image is capable of tile drawing (image is not tile) and the tiled
     * option is set in the space.
     */
    bool do_tile_drawing : 1;
  } flags;

  struct {
    DRWPass *image_pass;
    DRWPass *depth_pass;
  } passes;

  /**
   * Cache containing the float buffers when drawing byte images.
   */
  FloatBufferCache float_buffers;

  /** \brief Transform matrix to convert a normalized screen space coordinates to texture space. */
  float ss_to_texture[4][4];
  TextureInfo texture_infos[SCREEN_SPACE_DRAWING_MODE_TEXTURE_LEN];

 public:
  virtual ~IMAGE_InstanceData() = default;

  void clear_dirty_flag()
  {
    reset_dirty_flag(false);
  }
  void mark_all_texture_slots_dirty()
  {
    reset_dirty_flag(true);
  }

  void update_gpu_texture_allocations()
  {
    for (int i = 0; i < SCREEN_SPACE_DRAWING_MODE_TEXTURE_LEN; i++) {
      TextureInfo &info = texture_infos[i];
      const bool is_allocated = info.texture != nullptr;
      const bool is_visible = info.visible;
      const bool should_be_freed = !is_visible && is_allocated;
      const bool should_be_created = is_visible && !is_allocated;

      if (should_be_freed) {
        GPU_texture_free(info.texture);
        info.texture = nullptr;
      }

      if (should_be_created) {
        DRW_texture_ensure_fullscreen_2d(
            &info.texture, GPU_RGBA16F, static_cast<DRWTextureFlag>(0));
      }
      info.dirty |= should_be_created;
    }
  }

  void update_batches()
  {
    for (int i = 0; i < SCREEN_SPACE_DRAWING_MODE_TEXTURE_LEN; i++) {
      TextureInfo &info = texture_infos[i];
      if (!info.dirty) {
        continue;
      }
      BatchUpdater batch_updater(info);
      batch_updater.update_batch();
    }
  }

  void update_image_usage(const ImageUser *image_user)
  {
    ImageUsage usage(image, image_user);
    if (last_usage != usage) {
      last_usage = usage;
      reset_dirty_flag(true);
      float_buffers.clear();
    }
  }

 private:
  /** \brief Set dirty flag of all texture slots to the given value. */
  void reset_dirty_flag(bool new_value)
  {
    for (int i = 0; i < SCREEN_SPACE_DRAWING_MODE_TEXTURE_LEN; i++) {
      texture_infos[i].dirty = new_value;
    }
  }
};