Project import generated by Copybara.
GitOrigin-RevId: 43cd697ec87dcc5cab5051f27960bb77a057399d
This commit is contained in:
@@ -57,15 +57,14 @@
|
||||
#include <EGL/egl.h>
|
||||
#include <GLES2/gl2.h>
|
||||
#include <GLES2/gl2ext.h>
|
||||
|
||||
#ifdef __ANDROID__
|
||||
#if defined(__ANDROID__)
|
||||
// Weak-link all GL APIs included from this point on.
|
||||
// TODO: Annotate these with availability attributes for the
|
||||
// appropriate versions of Android, by including gl{3,31,31}.h and resetting
|
||||
// GL_APICALL for each.
|
||||
#undef GL_APICALL
|
||||
#define GL_APICALL __attribute__((weak_import)) KHRONOS_APICALL
|
||||
#endif // __ANDROID__
|
||||
#endif // defined(__ANDROID__)
|
||||
|
||||
#include <GLES3/gl32.h>
|
||||
|
||||
|
||||
@@ -83,6 +83,10 @@ class GlCalculatorHelperImpl {
|
||||
GLuint framebuffer_ = 0;
|
||||
|
||||
GpuResources& gpu_resources_;
|
||||
|
||||
// Necessary to compute for a given GlContext in order to properly enforce the
|
||||
// SetStandardTextureParams.
|
||||
bool can_linear_filter_float_textures_;
|
||||
};
|
||||
|
||||
} // namespace mediapipe
|
||||
|
||||
@@ -22,6 +22,17 @@ GlCalculatorHelperImpl::GlCalculatorHelperImpl(CalculatorContext* cc,
|
||||
GpuResources* gpu_resources)
|
||||
: gpu_resources_(*gpu_resources) {
|
||||
gl_context_ = gpu_resources_.gl_context(cc);
|
||||
// GL_ES_VERSION_2_0 and up (at least through ES 3.2) may contain the extension.
|
||||
// Checking against one also checks against higher ES versions. So this checks
|
||||
// against GLES >= 2.0.
|
||||
#if GL_ES_VERSION_2_0
|
||||
// No linear float filtering by default, check extensions.
|
||||
can_linear_filter_float_textures_ =
|
||||
gl_context_->HasGlExtension("OES_texture_float_linear");
|
||||
#else
|
||||
// Any float32 texture we create should automatically have linear filtering.
|
||||
can_linear_filter_float_textures_ = true;
|
||||
#endif // GL_ES_VERSION_2_0
|
||||
}
|
||||
|
||||
GlCalculatorHelperImpl::~GlCalculatorHelperImpl() {
|
||||
@@ -89,13 +100,15 @@ void GlCalculatorHelperImpl::BindFramebuffer(const GlTexture& dst) {
|
||||
|
||||
void GlCalculatorHelperImpl::SetStandardTextureParams(GLenum target,
|
||||
GLint internal_format) {
|
||||
// Default to using linear filter everywhere. For float32 textures, fall back
|
||||
// to GL_NEAREST if linear filtering unsupported.
|
||||
GLint filter;
|
||||
switch (internal_format) {
|
||||
case GL_R32F:
|
||||
case GL_RGBA32F:
|
||||
// 32F (unlike 16f) textures do not support texture filtering
|
||||
// 32F (unlike 16f) textures do not always support texture filtering
|
||||
// (According to OpenGL ES specification [TEXTURE IMAGE SPECIFICATION])
|
||||
filter = GL_NEAREST;
|
||||
filter = can_linear_filter_float_textures_ ? GL_LINEAR : GL_NEAREST;
|
||||
break;
|
||||
default:
|
||||
filter = GL_LINEAR;
|
||||
|
||||
@@ -203,6 +203,69 @@ bool GlContext::ParseGlVersion(absl::string_view version_string, GLint* major,
|
||||
return true;
|
||||
}
|
||||
|
||||
bool GlContext::HasGlExtension(absl::string_view extension) const {
|
||||
return gl_extensions_.find(extension) != gl_extensions_.end();
|
||||
}
|
||||
|
||||
// Function for GL3.0+ to query for and store all of our available GL extensions
|
||||
// in an easily-accessible set. The glGetString call is actually *not* required
|
||||
// to work with GL_EXTENSIONS for newer GL versions, so we must maintain both
|
||||
// variations of this function.
|
||||
::mediapipe::Status GlContext::GetGlExtensions() {
|
||||
gl_extensions_.clear();
|
||||
// glGetStringi only introduced in GL 3.0+; so we exit out this function if
|
||||
// we don't have that function defined, regardless of version number reported.
|
||||
// The function itself is also fully stubbed out if we're linking against an
|
||||
// API version without a glGetStringi declaration. Although Emscripten
|
||||
// sometimes provides this function, its default library implementation
|
||||
// appears to only provide glGetString, so we skip this for Emscripten
|
||||
// platforms to avoid possible undefined symbol or runtime errors.
|
||||
#if (GL_VERSION_3_0 || GL_ES_VERSION_3_0) && !defined(__EMSCRIPTEN__)
|
||||
if (!SymbolAvailable(&glGetStringi)) {
|
||||
LOG(ERROR) << "GL major version > 3.0 indicated, but glGetStringi not "
|
||||
<< "defined. Falling back to deprecated GL extensions querying "
|
||||
<< "method.";
|
||||
return ::mediapipe::InternalError("glGetStringi not defined, but queried");
|
||||
}
|
||||
int num_extensions = 0;
|
||||
glGetIntegerv(GL_NUM_EXTENSIONS, &num_extensions);
|
||||
if (glGetError() != 0) {
|
||||
return ::mediapipe::InternalError(
|
||||
"Error querying for number of extensions");
|
||||
}
|
||||
|
||||
for (int i = 0; i < num_extensions; ++i) {
|
||||
const GLubyte* res = glGetStringi(GL_EXTENSIONS, i);
|
||||
if (glGetError() != 0 || res == nullptr) {
|
||||
return ::mediapipe::InternalError(
|
||||
"Error querying for an extension by index");
|
||||
}
|
||||
const char* signed_res = reinterpret_cast<const char*>(res);
|
||||
gl_extensions_.insert(signed_res);
|
||||
}
|
||||
|
||||
return ::mediapipe::OkStatus();
|
||||
#else
|
||||
return ::mediapipe::InternalError("GL version mismatch in GlGetExtensions");
|
||||
#endif // (GL_VERSION_3_0 || GL_ES_VERSION_3_0) && !defined(__EMSCRIPTEN__)
|
||||
}
|
||||
|
||||
// Same as GetGlExtensions() above, but for pre-GL3.0, where glGetStringi did
|
||||
// not exist.
|
||||
::mediapipe::Status GlContext::GetGlExtensionsCompat() {
|
||||
gl_extensions_.clear();
|
||||
|
||||
const GLubyte* res = glGetString(GL_EXTENSIONS);
|
||||
if (glGetError() != 0 || res == nullptr) {
|
||||
LOG(ERROR) << "Error querying for GL extensions";
|
||||
return ::mediapipe::InternalError("Error querying for GL extensions");
|
||||
}
|
||||
const char* signed_res = reinterpret_cast<const char*>(res);
|
||||
gl_extensions_ = absl::StrSplit(signed_res, ' ');
|
||||
|
||||
return ::mediapipe::OkStatus();
|
||||
}
|
||||
|
||||
::mediapipe::Status GlContext::FinishInitialization(bool create_thread) {
|
||||
if (create_thread) {
|
||||
thread_ = absl::make_unique<GlContext::DedicatedThread>();
|
||||
@@ -232,8 +295,13 @@ bool GlContext::ParseGlVersion(absl::string_view version_string, GLint* major,
|
||||
|
||||
LOG(INFO) << "GL version: " << gl_major_version_ << "." << gl_minor_version_
|
||||
<< " (" << glGetString(GL_VERSION) << ")";
|
||||
|
||||
return ::mediapipe::OkStatus();
|
||||
if (gl_major_version_ >= 3) {
|
||||
auto status = GetGlExtensions();
|
||||
if (status.ok()) {
|
||||
return ::mediapipe::OkStatus();
|
||||
}
|
||||
}
|
||||
return GetGlExtensionsCompat();
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@@ -237,6 +237,10 @@ class GlContext : public std::enable_shared_from_this<GlContext> {
|
||||
static bool ParseGlVersion(absl::string_view version_string, GLint* major,
|
||||
GLint* minor);
|
||||
|
||||
// Simple query for GL extension support; only valid after GlContext has
|
||||
// finished its initialization successfully.
|
||||
bool HasGlExtension(absl::string_view extension) const;
|
||||
|
||||
int64_t gl_finish_count() { return gl_finish_count_; }
|
||||
|
||||
// Used by GlFinishSyncPoint. The count_to_pass cannot exceed the current
|
||||
@@ -346,6 +350,8 @@ class GlContext : public std::enable_shared_from_this<GlContext> {
|
||||
bool HasContext() const;
|
||||
bool CheckForGlErrors();
|
||||
void LogUncheckedGlErrors(bool had_gl_errors);
|
||||
::mediapipe::Status GetGlExtensions();
|
||||
::mediapipe::Status GetGlExtensionsCompat();
|
||||
|
||||
// The following ContextBinding functions have platform-specific
|
||||
// implementations.
|
||||
@@ -366,6 +372,10 @@ class GlContext : public std::enable_shared_from_this<GlContext> {
|
||||
GLint gl_major_version_ = 0;
|
||||
GLint gl_minor_version_ = 0;
|
||||
|
||||
// glGetString and glGetStringi both return pointers to static strings,
|
||||
// so we should be fine storing the extension pieces as string_view's.
|
||||
std::set<absl::string_view> gl_extensions_;
|
||||
|
||||
// Number of glFinish calls completed on the GL thread.
|
||||
// Changes should be guarded by mutex_. However, we use simple atomic
|
||||
// loads for efficiency on the fast path.
|
||||
|
||||
@@ -24,6 +24,19 @@ namespace mediapipe {
|
||||
#define _STRINGIFY(_x) __STRINGIFY(_x)
|
||||
#endif
|
||||
|
||||
// Our fragment shaders use DEFAULT_PRECISION to define the default precision
|
||||
// for a type. The macro strips out the precision declaration on desktop GL,
|
||||
// where it's not supported.
|
||||
//
|
||||
// Note: this does not use a raw std::string because some compilers don't handle
|
||||
// raw strings inside macros correctly. It uses a macro because we want to be
|
||||
// able to concatenate strings by juxtaposition. We want to concatenate strings
|
||||
// by juxtaposition so we can export const char* static data containing the
|
||||
// pre-expanded strings.
|
||||
//
|
||||
// TODO: this was written before we could rely on C++11 support.
|
||||
// Consider replacing it with constexpr std::string concatenation, or replacing
|
||||
// the static variables with functions.
|
||||
#define PRECISION_COMPAT \
|
||||
GLES_VERSION_COMPAT \
|
||||
"#ifdef GL_ES \n" \
|
||||
@@ -42,10 +55,15 @@ namespace mediapipe {
|
||||
"#define out varying\n" \
|
||||
"#endif // __VERSION__ < 130\n"
|
||||
|
||||
#define FRAGMENT_PREAMBLE \
|
||||
PRECISION_COMPAT \
|
||||
"#if __VERSION__ < 130\n" \
|
||||
"#define in varying\n" \
|
||||
// Note: on systems where highp precision for floats is not supported (look up
|
||||
// GL_FRAGMENT_PRECISION_HIGH), we replace it with mediump.
|
||||
#define FRAGMENT_PREAMBLE \
|
||||
PRECISION_COMPAT \
|
||||
"#if __VERSION__ < 130\n" \
|
||||
"#define in varying\n" \
|
||||
"#if GL_ES && !GL_FRAGMENT_PRECISION_HIGH\n" \
|
||||
"#define highp mediump\n" \
|
||||
"#endif // GL_ES && !GL_FRAGMENT_PRECISION_HIGH\n" \
|
||||
"#endif // __VERSION__ < 130\n"
|
||||
|
||||
const GLchar* const kMediaPipeVertexShaderPreamble = VERTEX_PREAMBLE;
|
||||
|
||||
Reference in New Issue
Block a user