#ifdef UNSAFE_BUFFERS_BUILD
#pragma allow_unsafe_buffers
#endif
#include "gpu/command_buffer/service/gl_utils.h"
#include <algorithm>
#include <unordered_set>
#include "build/build_config.h"
#include "gpu/command_buffer/common/capabilities.h"
#include "gpu/command_buffer/service/error_state.h"
#include "gpu/command_buffer/service/feature_info.h"
#include "gpu/command_buffer/service/gles2_cmd_copy_texture_chromium.h"
#include "gpu/command_buffer/service/logger.h"
#include "gpu/command_buffer/service/texture_manager.h"
#include "ui/gl/gl_version_info.h"
#if BUILDFLAG(IS_CHROMEOS_ASH)
#include <sys/stat.h>
#include "ui/gl/gl_surface_egl.h"
#endif
namespace gpu {
namespace gles2 {
namespace {
const int kASTCBlockSize = …;
const int kS3TCBlockWidth = …;
const int kS3TCBlockHeight = …;
const int kS3TCDXT1BlockSize = …;
const int kS3TCDXT3AndDXT5BlockSize = …;
const int kEACAndETC2BlockSize = …;
const int kBPTCBlockWidth = …;
const int kBPTCBlockHeight = …;
const int kRGTCBlockWidth = …;
const int kRGTCBlockHeight = …;
ASTCBlockArray;
const ASTCBlockArray kASTCBlockArray[] = …;
bool IsValidPVRTCSize(GLint level, GLsizei size) { … }
bool IsValidS3TCSizeForWebGLAndANGLE(GLint level, GLsizei size) { … }
const char* GetDebugSourceString(GLenum source) { … }
const char* GetDebugTypeString(GLenum type) { … }
const char* GetDebugSeverityString(GLenum severity) { … }
}
bool PrecisionMeetsSpecForHighpFloat(GLint rangeMin,
GLint rangeMax,
GLint precision) { … }
void QueryShaderPrecisionFormat(GLenum shader_type,
GLenum precision_type,
GLint* range,
GLint* precision) { … }
void PopulateNumericCapabilities(Capabilities* caps,
const FeatureInfo* feature_info) { … }
void PopulateGLCapabilities(GLCapabilities* caps,
const FeatureInfo* feature_info) { … }
#if BUILDFLAG(IS_CHROMEOS_ASH)
void PopulateDRMCapabilities(Capabilities* caps,
const FeatureInfo* feature_info) {
DCHECK(caps != nullptr);
if (!gl::GLSurfaceEGL::GetGLDisplayEGL() ||
!gl::GLSurfaceEGL::GetGLDisplayEGL()->IsInitialized() ||
!gl::GLSurfaceEGL::GetGLDisplayEGL()
->ext->b_EGL_EXT_image_dma_buf_import_modifiers ||
feature_info->workarounds()
.disable_egl_ext_image_dma_buf_import_modifiers ||
!gl::g_driver_egl.client_ext.b_EGL_EXT_device_query) {
return;
}
EGLDisplay egl_display = gl::GLSurfaceEGL::GetGLDisplayEGL()->GetDisplay();
DCHECK(egl_display != nullptr);
EGLDeviceEXT egl_device;
if (!eglQueryDisplayAttribEXT(egl_display, EGL_DEVICE_EXT,
(EGLAttrib*)&egl_device)) {
return;
}
gfx::ExtensionSet device_extension_set;
const char* device_extensions =
eglQueryDeviceStringEXT(egl_device, EGL_EXTENSIONS);
if (device_extensions) {
device_extension_set = gfx::MakeExtensionSet(device_extensions);
} else {
device_extension_set = gfx::ExtensionSet();
}
std::string drm_render_node;
if (gfx::HasExtension(device_extension_set,
"EGL_EXT_device_drm_render_node")) {
const char* path =
eglQueryDeviceStringEXT(egl_device, EGL_DRM_RENDER_NODE_FILE_EXT);
if (path)
drm_render_node = std::string(path);
}
if (drm_render_node.empty() &&
gfx::HasExtension(device_extension_set, "EGL_EXT_device_drm")) {
const char* path =
eglQueryDeviceStringEXT(egl_device, EGL_DRM_DEVICE_FILE_EXT);
if (path)
drm_render_node = std::string(path);
}
if (!drm_render_node.empty()) {
struct stat dev_stat;
if (stat(drm_render_node.c_str(), &dev_stat) == 0) {
static_assert(sizeof(dev_t) <= sizeof(caps->drm_device_id),
"unexpected dev_t size");
DCHECK(dev_stat.st_rdev);
caps->drm_device_id = dev_stat.st_rdev;
}
}
EGLint num_formats = 0;
if (eglQueryDmaBufFormatsEXT(egl_display, 0, nullptr, &num_formats) &&
num_formats > 0) {
std::vector<EGLint> formats_array(num_formats);
bool res = eglQueryDmaBufFormatsEXT(egl_display, num_formats,
formats_array.data(), &num_formats);
DCHECK(res);
for (EGLint format : formats_array) {
std::vector<uint64_t> modifiers;
EGLint num_modifiers = 0;
if (eglQueryDmaBufModifiersEXT(egl_display, format, 0, nullptr, nullptr,
&num_modifiers) &&
num_modifiers > 0) {
std::vector<EGLuint64KHR> modifiers_array(num_modifiers);
res = eglQueryDmaBufModifiersEXT(egl_display, format, num_modifiers,
modifiers_array.data(), nullptr,
&num_modifiers);
DCHECK(res);
for (uint64_t modifier : modifiers_array) {
modifiers.push_back(modifier);
}
}
caps->drm_formats_and_modifiers.emplace(format, modifiers);
}
}
}
#endif
bool CheckUniqueAndNonNullIds(GLsizei n, const GLuint* client_ids) { … }
const char* GetServiceVersionString(const FeatureInfo* feature_info) { … }
const char* GetServiceShadingLanguageVersionString(
const FeatureInfo* feature_info) { … }
void LogGLDebugMessage(GLenum source,
GLenum type,
GLuint id,
GLenum severity,
GLsizei length,
const GLchar* message,
Logger* error_logger) { … }
void InitializeGLDebugLogging(bool log_non_errors,
GLDEBUGPROC callback,
const void* user_param) { … }
bool ValidContextLostReason(GLenum reason) { … }
error::ContextLostReason GetContextLostReasonFromResetStatus(
GLenum reset_status) { … }
bool GetCompressedTexSizeInBytes(const char* function_name,
GLsizei width,
GLsizei height,
GLsizei depth,
GLenum format,
GLsizei* size_in_bytes,
ErrorState* error_state) { … }
bool ValidateCompressedFormatTarget(GLenum target, GLenum format) { … }
bool ValidateCompressedTexSubDimensions(GLenum target,
GLint level,
GLint xoffset,
GLint yoffset,
GLint zoffset,
GLsizei width,
GLsizei height,
GLsizei depth,
GLenum format,
Texture* texture,
const char** error_message) { … }
bool ValidateCompressedTexDimensions(GLenum target,
GLint level,
GLsizei width,
GLsizei height,
GLsizei depth,
GLenum format,
const char** error_message) { … }
bool ValidateCopyTexFormatHelper(const FeatureInfo* feature_info,
GLenum internal_format,
GLenum read_format,
GLenum read_type,
std::string* output_error_msg) { … }
CopyTextureMethod GetCopyTextureCHROMIUMMethod(const FeatureInfo* feature_info,
GLenum source_target,
GLint source_level,
GLenum source_internal_format,
GLenum source_type,
GLenum dest_target,
GLint dest_level,
GLenum dest_internal_format,
bool flip_y,
bool premultiply_alpha,
bool unpremultiply_alpha) { … }
bool ValidateCopyTextureCHROMIUMInternalFormats(const FeatureInfo* feature_info,
GLenum source_internal_format,
GLenum dest_internal_format,
std::string* output_error_msg) { … }
GLenum GetTextureBindingQuery(GLenum texture_type) { … }
bool IsASTCFormat(GLenum internal_format) { … }
bool IsCompressedTextureFormat(GLenum internal_format) { … }
Texture* CreateGLES2TextureWithLightRef(GLuint service_id, GLenum target) { … }
}
}