tor-browser

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

render_pipeline.cc (4863B)


      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 #include "lib/jxl/render_pipeline/render_pipeline.h"
      7 
      8 #include <jxl/memory_manager.h>
      9 
     10 #include <memory>
     11 #include <utility>
     12 
     13 #include "lib/jxl/base/rect.h"
     14 #include "lib/jxl/base/sanitizers.h"
     15 #include "lib/jxl/base/status.h"
     16 #include "lib/jxl/render_pipeline/low_memory_render_pipeline.h"
     17 #include "lib/jxl/render_pipeline/simple_render_pipeline.h"
     18 
     19 namespace jxl {
     20 
     21 Status RenderPipeline::Builder::AddStage(
     22    std::unique_ptr<RenderPipelineStage> stage) {
     23  if (!stage) return JXL_FAILURE("internal: no stage to add");
     24  stages_.push_back(std::move(stage));
     25  return true;
     26 }
     27 
     28 StatusOr<std::unique_ptr<RenderPipeline>> RenderPipeline::Builder::Finalize(
     29    FrameDimensions frame_dimensions) && {
     30  // Check that the last stage is not a kInOut stage for any channel, and that
     31  // there is at least one stage.
     32  JXL_ENSURE(!stages_.empty());
     33  for (size_t c = 0; c < num_c_; c++) {
     34    JXL_ENSURE(stages_.back()->GetChannelMode(c) !=
     35               RenderPipelineChannelMode::kInOut);
     36  }
     37 
     38  std::unique_ptr<RenderPipeline> res;
     39  if (use_simple_implementation_) {
     40    res = jxl::make_unique<SimpleRenderPipeline>(memory_manager_);
     41  } else {
     42    res = jxl::make_unique<LowMemoryRenderPipeline>(memory_manager_);
     43  }
     44 
     45  res->padding_.resize(stages_.size());
     46  for (size_t i = stages_.size(); i-- > 0;) {
     47    const auto& stage = stages_[i];
     48    res->padding_[i].resize(num_c_);
     49    if (i + 1 == stages_.size()) {
     50      continue;
     51    }
     52    for (size_t c = 0; c < num_c_; c++) {
     53      if (stage->GetChannelMode(c) == RenderPipelineChannelMode::kInOut) {
     54        res->padding_[i][c].first = DivCeil(res->padding_[i + 1][c].first,
     55                                            1 << stage->settings_.shift_x) +
     56                                    stage->settings_.border_x;
     57        res->padding_[i][c].second = DivCeil(res->padding_[i + 1][c].second,
     58                                             1 << stage->settings_.shift_y) +
     59                                     stage->settings_.border_y;
     60      } else {
     61        res->padding_[i][c] = res->padding_[i + 1][c];
     62      }
     63    }
     64  }
     65 
     66  res->frame_dimensions_ = frame_dimensions;
     67  res->group_completed_passes_.resize(frame_dimensions.num_groups);
     68  res->channel_shifts_.resize(stages_.size());
     69  res->channel_shifts_[0].resize(num_c_);
     70  for (size_t i = 1; i < stages_.size(); i++) {
     71    auto& stage = stages_[i - 1];
     72    for (size_t c = 0; c < num_c_; c++) {
     73      if (stage->GetChannelMode(c) == RenderPipelineChannelMode::kInOut) {
     74        res->channel_shifts_[0][c].first += stage->settings_.shift_x;
     75        res->channel_shifts_[0][c].second += stage->settings_.shift_y;
     76      }
     77    }
     78  }
     79  for (size_t i = 1; i < stages_.size(); i++) {
     80    auto& stage = stages_[i - 1];
     81    res->channel_shifts_[i].resize(num_c_);
     82    for (size_t c = 0; c < num_c_; c++) {
     83      if (stage->GetChannelMode(c) == RenderPipelineChannelMode::kInOut) {
     84        res->channel_shifts_[i][c].first =
     85            res->channel_shifts_[i - 1][c].first - stage->settings_.shift_x;
     86        res->channel_shifts_[i][c].second =
     87            res->channel_shifts_[i - 1][c].second - stage->settings_.shift_y;
     88      } else {
     89        res->channel_shifts_[i][c].first = res->channel_shifts_[i - 1][c].first;
     90        res->channel_shifts_[i][c].second =
     91            res->channel_shifts_[i - 1][c].second;
     92      }
     93    }
     94  }
     95  res->stages_ = std::move(stages_);
     96  JXL_RETURN_IF_ERROR(res->Init());
     97  return res;
     98 }
     99 
    100 RenderPipelineInput RenderPipeline::GetInputBuffers(size_t group_id,
    101                                                    size_t thread_id) {
    102  RenderPipelineInput ret;
    103  JXL_DASSERT(group_id < group_completed_passes_.size());
    104  ret.group_id_ = group_id;
    105  ret.thread_id_ = thread_id;
    106  ret.pipeline_ = this;
    107  ret.buffers_ = PrepareBuffers(group_id, thread_id);
    108  return ret;
    109 }
    110 
    111 Status RenderPipeline::InputReady(
    112    size_t group_id, size_t thread_id,
    113    const std::vector<std::pair<ImageF*, Rect>>& buffers) {
    114  JXL_ENSURE(group_id < group_completed_passes_.size());
    115  group_completed_passes_[group_id]++;
    116  for (size_t i = 0; i < buffers.size(); ++i) {
    117    (void)i;
    118    JXL_CHECK_PLANE_INITIALIZED(*buffers[i].first, buffers[i].second, i);
    119  }
    120 
    121  JXL_RETURN_IF_ERROR(ProcessBuffers(group_id, thread_id));
    122  return true;
    123 }
    124 
    125 Status RenderPipeline::PrepareForThreads(size_t num, bool use_group_ids) {
    126  for (const auto& stage : stages_) {
    127    JXL_RETURN_IF_ERROR(stage->PrepareForThreads(num));
    128  }
    129  JXL_RETURN_IF_ERROR(PrepareForThreadsInternal(num, use_group_ids));
    130  return true;
    131 }
    132 
    133 Status RenderPipelineInput::Done() {
    134  JXL_ENSURE(pipeline_);
    135  JXL_RETURN_IF_ERROR(pipeline_->InputReady(group_id_, thread_id_, buffers_));
    136  return true;
    137 }
    138 
    139 }  // namespace jxl