Project import generated by Copybara.

GitOrigin-RevId: 43cd697ec87dcc5cab5051f27960bb77a057399d
This commit is contained in:
MediaPipe Team
2020-03-20 15:28:51 -07:00
committed by jqtang
parent 3b6d3c4058
commit 1722d4b8a2
71 changed files with 6114 additions and 626 deletions
+2 -3
View File
@@ -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;
+70 -2
View File
@@ -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();
});
}
+10
View File
@@ -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.
+22 -4
View File
@@ -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;