tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

render_pipeline.h (5019B)


      1 // Copyright (c) the JPEG XL Project Authors. All rights reserved.
      2 //
      3 // Use of this source code is governed by a BSD-style
      4 // license that can be found in the LICENSE file.
      5 
      6 #ifndef LIB_JXL_RENDER_PIPELINE_RENDER_PIPELINE_H_
      7 #define LIB_JXL_RENDER_PIPELINE_RENDER_PIPELINE_H_
      8 
      9 #include <jxl/memory_manager.h>
     10 
     11 #include <algorithm>
     12 #include <cstddef>
     13 #include <cstdint>
     14 #include <memory>
     15 #include <utility>
     16 #include <vector>
     17 
     18 #include "lib/jxl/base/rect.h"
     19 #include "lib/jxl/base/status.h"
     20 #include "lib/jxl/frame_dimensions.h"
     21 #include "lib/jxl/image.h"
     22 #include "lib/jxl/render_pipeline/render_pipeline_stage.h"
     23 
     24 namespace jxl {
     25 
     26 // Interface to provide input to the rendering pipeline. When this object is
     27 // destroyed, all the data in the provided ImageF's Rects must have been
     28 // initialized.
     29 class RenderPipelineInput {
     30 public:
     31  RenderPipelineInput(const RenderPipelineInput&) = delete;
     32  RenderPipelineInput(RenderPipelineInput&& other) noexcept {
     33    *this = std::move(other);
     34  }
     35  RenderPipelineInput& operator=(RenderPipelineInput&& other) noexcept {
     36    pipeline_ = other.pipeline_;
     37    group_id_ = other.group_id_;
     38    thread_id_ = other.thread_id_;
     39    buffers_ = std::move(other.buffers_);
     40    other.pipeline_ = nullptr;
     41    return *this;
     42  }
     43 
     44  RenderPipelineInput() = default;
     45  Status Done();
     46 
     47  const std::pair<ImageF*, Rect>& GetBuffer(size_t c) const {
     48    JXL_DASSERT(c < buffers_.size());
     49    return buffers_[c];
     50  }
     51 
     52 private:
     53  RenderPipeline* pipeline_ = nullptr;
     54  size_t group_id_;
     55  size_t thread_id_;
     56  std::vector<std::pair<ImageF*, Rect>> buffers_;
     57  friend class RenderPipeline;
     58 };
     59 
     60 class RenderPipeline {
     61 public:
     62  class Builder {
     63   public:
     64    explicit Builder(JxlMemoryManager* memory_manager, size_t num_c)
     65        : memory_manager_(memory_manager), num_c_(num_c) {
     66      JXL_DASSERT(num_c > 0);
     67    }
     68 
     69    // Adds a stage to the pipeline. Must be called at least once; the last
     70    // added stage cannot have kInOut channels.
     71    Status AddStage(std::unique_ptr<RenderPipelineStage> stage);
     72 
     73    // Enables using the simple (i.e. non-memory-efficient) implementation of
     74    // the pipeline.
     75    void UseSimpleImplementation() { use_simple_implementation_ = true; }
     76 
     77    // Finalizes setup of the pipeline. Shifts for all channels should be 0 at
     78    // this point.
     79    StatusOr<std::unique_ptr<RenderPipeline>> Finalize(
     80        FrameDimensions frame_dimensions) &&;
     81 
     82   private:
     83    JxlMemoryManager* memory_manager_;
     84    std::vector<std::unique_ptr<RenderPipelineStage>> stages_;
     85    size_t num_c_;
     86    bool use_simple_implementation_ = false;
     87  };
     88 
     89  friend class Builder;
     90 
     91  virtual ~RenderPipeline() = default;
     92 
     93  Status IsInitialized() const {
     94    for (const auto& stage : stages_) {
     95      JXL_RETURN_IF_ERROR(stage->IsInitialized());
     96    }
     97    return true;
     98  }
     99 
    100  // Allocates storage to run with `num` threads. If `use_group_ids` is true,
    101  // storage is allocated for each group, not each thread. The behaviour is
    102  // undefined if calling this function multiple times with a different value
    103  // for `use_group_ids`.
    104  Status PrepareForThreads(size_t num, bool use_group_ids);
    105 
    106  // Retrieves a buffer where input data should be stored by the callee. When
    107  // input has been provided for all buffers, the pipeline will complete its
    108  // processing. This method may be called multiple times concurrently from
    109  // different threads, provided that a different `thread_id` is given.
    110  RenderPipelineInput GetInputBuffers(size_t group_id, size_t thread_id);
    111 
    112  size_t PassesWithAllInput() const {
    113    return *std::min_element(group_completed_passes_.begin(),
    114                             group_completed_passes_.end());
    115  }
    116 
    117  virtual void ClearDone(size_t i) {}
    118 
    119 protected:
    120  explicit RenderPipeline(JxlMemoryManager* memory_manager)
    121      : memory_manager_(memory_manager) {}
    122  JxlMemoryManager* memory_manager_;
    123 
    124  std::vector<std::unique_ptr<RenderPipelineStage>> stages_;
    125  // Shifts for every channel at the input of each stage.
    126  std::vector<std::vector<std::pair<size_t, size_t>>> channel_shifts_;
    127 
    128  // Amount of (cumulative) padding required by each stage and channel, in
    129  // either direction.
    130  std::vector<std::vector<std::pair<size_t, size_t>>> padding_;
    131 
    132  FrameDimensions frame_dimensions_;
    133 
    134  std::vector<uint8_t> group_completed_passes_;
    135 
    136  friend class RenderPipelineInput;
    137 
    138 private:
    139  Status InputReady(size_t group_id, size_t thread_id,
    140                    const std::vector<std::pair<ImageF*, Rect>>& buffers);
    141 
    142  virtual std::vector<std::pair<ImageF*, Rect>> PrepareBuffers(
    143      size_t group_id, size_t thread_id) = 0;
    144 
    145  virtual Status ProcessBuffers(size_t group_id, size_t thread_id) = 0;
    146 
    147  // Note that this method may be called multiple times with different (or
    148  // equal) `num`.
    149  virtual Status PrepareForThreadsInternal(size_t num, bool use_group_ids) = 0;
    150 
    151  // Called once frame dimensions and stages are known.
    152  virtual Status Init() { return true; }
    153 };
    154 
    155 }  // namespace jxl
    156 
    157 #endif  // LIB_JXL_RENDER_PIPELINE_RENDER_PIPELINE_H_