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

gpu / ipc / service / built_in_shader_cache_writer.cc [blame]

// Copyright 2023 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "gpu/ipc/service/built_in_shader_cache_writer.h"

#include "base/command_line.h"
#include "base/containers/span.h"
#include "base/files/file_path.h"
#include "base/numerics/safe_conversions.h"
#include "gpu/config/gpu_switches.h"

namespace gpu {

namespace {

// Returns the path to use is no path is supplied.
base::FilePath GetDefaultPath() {
  auto path = base::CommandLine::ForCurrentProcess()->GetSwitchValuePath(
      switches::kShaderCachePath);
  return path.empty() ? base::FilePath::FromASCII("/tmp/shader") : path;
}

}  // namespace

const uint32_t BuiltInShaderCacheWriter::kSignature = 0x53484430;

BuiltInShaderCacheWriter::BuiltInShaderCacheWriter(const base::FilePath& path)
    : file_(path.empty() ? GetDefaultPath() : path,
            base::File::FLAG_OPEN_ALWAYS | base::File::FLAG_OPEN_TRUNCATED |
                base::File::FLAG_WRITE) {
  valid_file_ = file_.IsValid() && file_.WriteAtCurrentPosAndCheck(
                                       base::byte_span_from_ref(kSignature));
}

BuiltInShaderCacheWriter::~BuiltInShaderCacheWriter() = default;

void BuiltInShaderCacheWriter::OnValueAddedToCache(
    const std::vector<uint8_t>& key,
    const std::vector<uint8_t>& value) {
  CHECK(!key.empty());
  CHECK(!value.empty());
  LOG(ERROR) << "Added shader cache value, count is " << ++add_count_;
  valid_file_ &= WriteVectorToFile(key);
  valid_file_ &= WriteVectorToFile(value);
  if (valid_file_) {
    // Flush after every entry because the gpu is not cleanly shutdown.
    file_.Flush();
  }
}

bool BuiltInShaderCacheWriter::WriteVectorToFile(
    const std::vector<uint8_t>& value) {
  // The cache has a max size which is represented by a uint32_t (see
  // `GpuPreferences::gpu_program_cache_size`), additionally the current max
  // is ~6mb (anything above the max is dropped, and shouldn't result in
  // calling this). For this reason `uint32_t` is used.
  const uint32_t size = base::checked_cast<uint32_t>(value.size());
  return file_.WriteAtCurrentPosAndCheck(base::byte_span_from_ref(size)) &&
         file_.WriteAtCurrentPosAndCheck(value);
}

}  // namespace gpu