| // Copyright 2015 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/command_buffer/service/sampler_manager.h" | |
| #include "base/check_op.h" | |
| #include "base/functional/bind.h" | |
| #include "gpu/command_buffer/common/gles2_cmd_format.h" | |
| #include "gpu/command_buffer/service/error_state.h" | |
| #include "gpu/command_buffer/service/feature_info.h" | |
| #include "gpu/command_buffer/service/gles2_cmd_decoder.h" | |
| #include "ui/gl/gl_bindings.h" | |
| #include "ui/gl/gl_context.h" | |
| #include "ui/gl/gl_fence.h" | |
| #include "ui/gl/gpu_timing.h" | |
| namespace gpu { | |
| namespace gles2 { | |
| SamplerState::SamplerState() | |
| : min_filter(GL_NEAREST_MIPMAP_LINEAR), | |
| mag_filter(GL_LINEAR), | |
| wrap_r(GL_REPEAT), | |
| wrap_s(GL_REPEAT), | |
| wrap_t(GL_REPEAT), | |
| compare_func(GL_LEQUAL), | |
| compare_mode(GL_NONE), | |
| max_lod(1000.0f), | |
| min_lod(-1000.0f), | |
| max_anisotropy_ext(1.0f) {} | |
| Sampler::Sampler(SamplerManager* manager, GLuint client_id, GLuint service_id) | |
| : manager_(manager), | |
| client_id_(client_id), | |
| service_id_(service_id), | |
| deleted_(false) { | |
| DCHECK(manager); | |
| } | |
| Sampler::~Sampler() { | |
| if (manager_->have_context_) { | |
| glDeleteSamplers(1, &service_id_); | |
| } | |
| } | |
| GLenum Sampler::SetParameteri( | |
| const FeatureInfo* feature_info, GLenum pname, GLint param) { | |
| DCHECK(feature_info); | |
| switch (pname) { | |
| case GL_TEXTURE_MIN_LOD: | |
| case GL_TEXTURE_MAX_LOD: { | |
| GLfloat fparam = static_cast<GLfloat>(param); | |
| return SetParameterf(feature_info, pname, fparam); | |
| } | |
| case GL_TEXTURE_MIN_FILTER: | |
| if (!feature_info->validators()->texture_min_filter_mode.IsValid(param)) { | |
| return GL_INVALID_ENUM; | |
| } | |
| sampler_state_.min_filter = param; | |
| break; | |
| case GL_TEXTURE_MAG_FILTER: | |
| if (!feature_info->validators()->texture_mag_filter_mode.IsValid(param)) { | |
| return GL_INVALID_ENUM; | |
| } | |
| sampler_state_.mag_filter = param; | |
| break; | |
| case GL_TEXTURE_WRAP_R: | |
| if (!feature_info->validators()->texture_wrap_mode.IsValid(param)) { | |
| return GL_INVALID_ENUM; | |
| } | |
| sampler_state_.wrap_r = param; | |
| break; | |
| case GL_TEXTURE_WRAP_S: | |
| if (!feature_info->validators()->texture_wrap_mode.IsValid(param)) { | |
| return GL_INVALID_ENUM; | |
| } | |
| sampler_state_.wrap_s = param; | |
| break; | |
| case GL_TEXTURE_WRAP_T: | |
| if (!feature_info->validators()->texture_wrap_mode.IsValid(param)) { | |
| return GL_INVALID_ENUM; | |
| } | |
| sampler_state_.wrap_t = param; | |
| break; | |
| case GL_TEXTURE_COMPARE_FUNC: | |
| if (!feature_info->validators()->texture_compare_func.IsValid(param)) { | |
| return GL_INVALID_ENUM; | |
| } | |
| sampler_state_.compare_func = param; | |
| break; | |
| case GL_TEXTURE_COMPARE_MODE: | |
| if (!feature_info->validators()->texture_compare_mode.IsValid(param)) { | |
| return GL_INVALID_ENUM; | |
| } | |
| sampler_state_.compare_mode = param; | |
| break; | |
| default: | |
| return GL_INVALID_ENUM; | |
| } | |
| return GL_NO_ERROR; | |
| } | |
| GLenum Sampler::SetParameterf( | |
| const FeatureInfo* feature_info, GLenum pname, GLfloat param) { | |
| switch (pname) { | |
| case GL_TEXTURE_MIN_FILTER: | |
| case GL_TEXTURE_MAG_FILTER: | |
| case GL_TEXTURE_WRAP_R: | |
| case GL_TEXTURE_WRAP_S: | |
| case GL_TEXTURE_WRAP_T: | |
| case GL_TEXTURE_COMPARE_FUNC: | |
| case GL_TEXTURE_COMPARE_MODE: { | |
| GLint iparam = static_cast<GLint>(std::round(param)); | |
| return SetParameteri(feature_info, pname, iparam); | |
| } | |
| case GL_TEXTURE_MIN_LOD: | |
| sampler_state_.min_lod = param; | |
| break; | |
| case GL_TEXTURE_MAX_LOD: | |
| sampler_state_.max_lod = param; | |
| break; | |
| case GL_TEXTURE_MAX_ANISOTROPY_EXT: | |
| sampler_state_.max_anisotropy_ext = param; | |
| break; | |
| default: | |
| return GL_INVALID_ENUM; | |
| } | |
| return GL_NO_ERROR; | |
| } | |
| SamplerManager::SamplerManager(FeatureInfo* feature_info) | |
| : feature_info_(feature_info), | |
| have_context_(true) { | |
| } | |
| SamplerManager::~SamplerManager() { | |
| DCHECK(samplers_.empty()); | |
| } | |
| void SamplerManager::Destroy(bool have_context) { | |
| have_context_ = have_context; | |
| while (!samplers_.empty()) { | |
| Sampler* sampler = samplers_.begin()->second.get(); | |
| sampler->MarkAsDeleted(); | |
| samplers_.erase(samplers_.begin()); | |
| } | |
| } | |
| Sampler* SamplerManager::CreateSampler(GLuint client_id, GLuint service_id) { | |
| DCHECK_NE(0u, service_id); | |
| auto result = samplers_.insert(std::make_pair( | |
| client_id, base::MakeRefCounted<Sampler>(this, client_id, service_id))); | |
| DCHECK(result.second); | |
| return result.first->second.get(); | |
| } | |
| Sampler* SamplerManager::GetSampler(GLuint client_id) { | |
| SamplerMap::iterator it = samplers_.find(client_id); | |
| return it != samplers_.end() ? it->second.get() : nullptr; | |
| } | |
| void SamplerManager::RemoveSampler(GLuint client_id) { | |
| SamplerMap::iterator it = samplers_.find(client_id); | |
| if (it != samplers_.end()) { | |
| Sampler* sampler = it->second.get(); | |
| sampler->MarkAsDeleted(); | |
| samplers_.erase(it); | |
| } | |
| } | |
| void SamplerManager::SetParameteri( | |
| const char* function_name, ErrorState* error_state, | |
| Sampler* sampler, GLenum pname, GLint param) { | |
| DCHECK(error_state); | |
| DCHECK(sampler); | |
| GLenum result = sampler->SetParameteri(feature_info_.get(), pname, param); | |
| if (result != GL_NO_ERROR) { | |
| if (result == GL_INVALID_ENUM) { | |
| ERRORSTATE_SET_GL_ERROR_INVALID_ENUM( | |
| error_state, function_name, param, "param"); | |
| } else { | |
| ERRORSTATE_SET_GL_ERROR_INVALID_PARAMI( | |
| error_state, result, function_name, pname, param); | |
| } | |
| } else { | |
| glSamplerParameteri(sampler->service_id(), pname, param); | |
| } | |
| } | |
| void SamplerManager::SetParameterf( | |
| const char* function_name, ErrorState* error_state, | |
| Sampler* sampler, GLenum pname, GLfloat param) { | |
| DCHECK(error_state); | |
| DCHECK(sampler); | |
| GLenum result = sampler->SetParameterf(feature_info_.get(), pname, param); | |
| if (result != GL_NO_ERROR) { | |
| if (result == GL_INVALID_ENUM) { | |
| ERRORSTATE_SET_GL_ERROR_INVALID_ENUM( | |
| error_state, function_name, param, "param"); | |
| } else { | |
| ERRORSTATE_SET_GL_ERROR_INVALID_PARAMI( | |
| error_state, result, function_name, pname, param); | |
| } | |
| } else { | |
| glSamplerParameterf(sampler->service_id(), pname, param); | |
| } | |
| } | |
| } // namespace gles2 | |
| } // namespace gpu |