libjxl

FORK: libjxl patches used on blog
git clone https://git.neptards.moe/blog/libjxl.git
Log | Files | Refs | Submodules | README | LICENSE

render_pipeline.h (4521B)


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