blob: 886e2e77e9c743ee43ac8a2da5f0481e43361654 [file] [log] [blame]
/*
* Copyright 2021 The Chromium OS Authors. All rights reserved.
* Use of this source code is governed by a BSD-style license that can be
* found in the LICENSE file.
*/
#include "gpu/gles/shader.h"
#include <algorithm>
#include <utility>
#include <base/files/file_util.h>
#include "cros-camera/common.h"
namespace cros {
// static
base::Optional<Shader> Shader::FromFile(GLenum type,
base::FilePath shader_file_path) {
if (!base::PathIsReadable(shader_file_path)) {
LOGF(ERROR) << "Invalid shader file: " << shader_file_path;
return base::nullopt;
}
std::string source_code;
bool ok = base::ReadFileToString(shader_file_path, &source_code);
if (!ok) {
LOGF(ERROR) << "Failed to load shader source code from file: "
<< shader_file_path;
return base::nullopt;
}
Shader shader(type, std::move(source_code));
if (!shader.IsValid()) {
return base::nullopt;
}
return base::Optional<Shader>(std::move(shader));
}
Shader::Shader(GLenum type, const std::string source_code) {
id_ = glCreateShader(type);
if (id_ == 0) {
LOGF(ERROR) << "Failed to generate shader";
return;
}
VLOGF(1) << "Compiling shader:\n" << source_code.data();
const char* str = source_code.data();
const GLint length = source_code.size();
glShaderSource(id_, 1, &str, &length);
glCompileShader(id_);
GLint shader_log_length;
glGetShaderiv(id_, GL_INFO_LOG_LENGTH, &shader_log_length);
std::string shader_log(std::max(shader_log_length - 1, 0), '\0');
glGetShaderInfoLog(id_, shader_log_length, /*length=*/nullptr,
shader_log.data());
GLint compile_status;
glGetShaderiv(id_, GL_COMPILE_STATUS, &compile_status);
if (static_cast<GLboolean>(compile_status) == GL_FALSE) {
glDeleteShader(id_);
id_ = 0;
LOGF(ERROR) << "Shader failed to compile:\n" << shader_log;
return;
}
}
Shader::Shader(Shader&& other) {
*this = std::move(other);
}
Shader& Shader::operator=(Shader&& other) {
if (this != &other) {
Invalidate();
id_ = other.id_;
other.id_ = 0;
}
return *this;
}
Shader::~Shader() {
Invalidate();
}
void Shader::Invalidate() {
if (IsValid()) {
glDeleteShader(id_);
id_ = 0;
}
}
} // namespace cros