Project import generated by Copybara.
GitOrigin-RevId: d073f8e21be2fcc0e503cb97c6695078b6b75310
This commit is contained in:
+22
-1
@@ -15,6 +15,7 @@
|
||||
load("//mediapipe/gpu:metal.bzl", "metal_library")
|
||||
load("@build_bazel_rules_apple//apple:ios.bzl", "ios_unit_test")
|
||||
load("//mediapipe/framework/port:build_config.bzl", "mediapipe_cc_proto_library")
|
||||
load("//mediapipe/framework:mediapipe_cc_test.bzl", "mediapipe_cc_test")
|
||||
|
||||
licenses(["notice"])
|
||||
|
||||
@@ -166,6 +167,7 @@ cc_library(
|
||||
deps = [
|
||||
":gl_base",
|
||||
":gl_thread_collector",
|
||||
":gpu_buffer_format",
|
||||
"//mediapipe/framework:executor",
|
||||
"//mediapipe/framework/port:logging",
|
||||
"//mediapipe/framework/port:ret_check",
|
||||
@@ -364,13 +366,13 @@ cc_library(
|
||||
hdrs = [
|
||||
"gpu_shared_data_internal.h",
|
||||
],
|
||||
defines = ["MEDIAPIPE_DISABLE_GPU"],
|
||||
visibility = ["//visibility:private"],
|
||||
deps = [
|
||||
":graph_support",
|
||||
"//mediapipe/framework:calculator_context",
|
||||
"//mediapipe/framework:calculator_node",
|
||||
"//mediapipe/framework:executor",
|
||||
"//mediapipe/framework:port",
|
||||
"//mediapipe/framework/deps:no_destructor",
|
||||
"//mediapipe/framework/port:ret_check",
|
||||
"//mediapipe/gpu:gl_context_options_cc_proto",
|
||||
@@ -560,6 +562,7 @@ cc_library(
|
||||
"//mediapipe/framework:packet_set",
|
||||
"//mediapipe/framework:packet_type",
|
||||
"//mediapipe/framework:timestamp",
|
||||
"//mediapipe/framework/formats:image",
|
||||
"//mediapipe/framework/formats:image_frame",
|
||||
"//mediapipe/framework/port:logging",
|
||||
"//mediapipe/framework/port:ret_check",
|
||||
@@ -597,6 +600,7 @@ objc_library(
|
||||
":gpu_shared_data_internal",
|
||||
":shader_util",
|
||||
"//mediapipe/framework:calculator_framework",
|
||||
"//mediapipe/framework/formats:image",
|
||||
"//mediapipe/objc:mediapipe_framework_ios",
|
||||
"//mediapipe/objc:util",
|
||||
],
|
||||
@@ -904,6 +908,23 @@ objc_library(
|
||||
alwayslink = 1,
|
||||
)
|
||||
|
||||
objc_library(
|
||||
name = "mps_threshold_calculator",
|
||||
srcs = ["MPSThresholdCalculator.mm"],
|
||||
copts = ["-std=c++17"],
|
||||
sdk_frameworks = [
|
||||
"CoreVideo",
|
||||
"Metal",
|
||||
"MetalPerformanceShaders",
|
||||
],
|
||||
visibility = ["//visibility:public"],
|
||||
deps = [
|
||||
":MPPMetalHelper",
|
||||
"//mediapipe/objc:mediapipe_framework_ios",
|
||||
],
|
||||
alwayslink = 1,
|
||||
)
|
||||
|
||||
MIN_IOS_VERSION = "9.0" # For thread_local.
|
||||
|
||||
test_suite(
|
||||
|
||||
@@ -41,7 +41,7 @@ NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
/// Configures a calculator's contract for accessing GPU resources.
|
||||
/// Calculators should use this in GetContract.
|
||||
+ (::mediapipe::Status)updateContract:(mediapipe::CalculatorContract*)cc;
|
||||
+ (absl::Status)updateContract:(mediapipe::CalculatorContract*)cc;
|
||||
|
||||
/// Deprecated initializer.
|
||||
- (instancetype)initWithSidePackets:(const mediapipe::PacketSet&)inputSidePackets;
|
||||
@@ -51,7 +51,7 @@ NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
/// Configures a calculator's side packets for accessing GPU resources.
|
||||
/// Calculators should use this in FillExpectations.
|
||||
+ (::mediapipe::Status)setupInputSidePackets:(mediapipe::PacketTypeSet*)inputSidePackets;
|
||||
+ (absl::Status)setupInputSidePackets:(mediapipe::PacketTypeSet*)inputSidePackets;
|
||||
|
||||
/// Get a metal command buffer.
|
||||
/// Calculators should use this method instead of getting a buffer from the
|
||||
|
||||
@@ -54,7 +54,7 @@ class MetalHelperLegacySupport {
|
||||
return [self initWithGpuResources:&cc->Service(mediapipe::kGpuService).GetObject()];
|
||||
}
|
||||
|
||||
+ (::mediapipe::Status)updateContract:(mediapipe::CalculatorContract*)cc {
|
||||
+ (absl::Status)updateContract:(mediapipe::CalculatorContract*)cc {
|
||||
cc->UseService(mediapipe::kGpuService);
|
||||
// Allow the legacy side packet to be provided, too, for backwards
|
||||
// compatibility with existing graphs. It will just be ignored.
|
||||
@@ -63,7 +63,7 @@ class MetalHelperLegacySupport {
|
||||
if (id.IsValid()) {
|
||||
input_side_packets.Get(id).Set<mediapipe::GpuSharedData*>();
|
||||
}
|
||||
return ::mediapipe::OkStatus();
|
||||
return absl::OkStatus();
|
||||
}
|
||||
|
||||
// Legacy support.
|
||||
@@ -85,7 +85,7 @@ class MetalHelperLegacySupport {
|
||||
}
|
||||
|
||||
// Legacy support.
|
||||
+ (::mediapipe::Status)setupInputSidePackets:(mediapipe::PacketTypeSet*)inputSidePackets {
|
||||
+ (absl::Status)setupInputSidePackets:(mediapipe::PacketTypeSet*)inputSidePackets {
|
||||
auto cc = mediapipe::MetalHelperLegacySupport::GetCalculatorContract();
|
||||
if (cc) {
|
||||
CHECK_EQ(inputSidePackets, &cc->InputSidePackets());
|
||||
@@ -101,7 +101,7 @@ class MetalHelperLegacySupport {
|
||||
<< "A " << mediapipe::kGpuSharedTagName
|
||||
<< " input side packet is required here.";
|
||||
inputSidePackets->Get(id).Set<mediapipe::GpuSharedData*>();
|
||||
return ::mediapipe::OkStatus();
|
||||
return absl::OkStatus();
|
||||
}
|
||||
|
||||
- (id<MTLDevice>)mtlDevice {
|
||||
|
||||
@@ -69,7 +69,7 @@
|
||||
#include <GLES3/gl32.h>
|
||||
|
||||
// When using the Linux EGL headers, we may end up pulling a
|
||||
// "#define Status int" from Xlib.h, which interferes with mediapipe::Status.
|
||||
// "#define Status int" from Xlib.h, which interferes with absl::Status.
|
||||
#undef Status
|
||||
|
||||
// More crud from X
|
||||
|
||||
@@ -14,6 +14,7 @@
|
||||
|
||||
#include "mediapipe/gpu/gl_calculator_helper.h"
|
||||
|
||||
#include "mediapipe/framework/formats/image.h"
|
||||
#include "mediapipe/framework/formats/image_frame.h"
|
||||
#include "mediapipe/framework/legacy_calculator_support.h"
|
||||
#include "mediapipe/framework/port/canonical_errors.h"
|
||||
@@ -39,12 +40,12 @@ GlCalculatorHelper::GlCalculatorHelper() {}
|
||||
|
||||
GlCalculatorHelper::~GlCalculatorHelper() {}
|
||||
|
||||
::mediapipe::Status GlCalculatorHelper::Open(CalculatorContext* cc) {
|
||||
absl::Status GlCalculatorHelper::Open(CalculatorContext* cc) {
|
||||
CHECK(cc);
|
||||
// TODO return error from impl_ (needs two-stage init)
|
||||
impl_ = absl::make_unique<GlCalculatorHelperImpl>(
|
||||
cc, &cc->Service(kGpuService).GetObject());
|
||||
return ::mediapipe::OkStatus();
|
||||
return absl::OkStatus();
|
||||
}
|
||||
|
||||
void GlCalculatorHelper::InitializeForTest(GpuSharedData* gpu_shared) {
|
||||
@@ -57,7 +58,7 @@ void GlCalculatorHelper::InitializeForTest(GpuResources* gpu_resources) {
|
||||
}
|
||||
|
||||
// static
|
||||
::mediapipe::Status GlCalculatorHelper::UpdateContract(CalculatorContract* cc) {
|
||||
absl::Status GlCalculatorHelper::UpdateContract(CalculatorContract* cc) {
|
||||
cc->UseService(kGpuService);
|
||||
// Allow the legacy side packet to be provided, too, for backwards
|
||||
// compatibility with existing graphs. It will just be ignored.
|
||||
@@ -66,11 +67,11 @@ void GlCalculatorHelper::InitializeForTest(GpuResources* gpu_resources) {
|
||||
if (id.IsValid()) {
|
||||
input_side_packets.Get(id).Set<GpuSharedData*>();
|
||||
}
|
||||
return ::mediapipe::OkStatus();
|
||||
return absl::OkStatus();
|
||||
}
|
||||
|
||||
// static
|
||||
::mediapipe::Status GlCalculatorHelper::SetupInputSidePackets(
|
||||
absl::Status GlCalculatorHelper::SetupInputSidePackets(
|
||||
PacketTypeSet* input_side_packets) {
|
||||
auto cc = LegacyCalculatorSupport::Scoped<CalculatorContract>::current();
|
||||
if (cc) {
|
||||
@@ -87,12 +88,12 @@ void GlCalculatorHelper::InitializeForTest(GpuResources* gpu_resources) {
|
||||
RET_CHECK(id.IsValid()) << "A " << mediapipe::kGpuSharedTagName
|
||||
<< " input side packet is required here.";
|
||||
input_side_packets->Get(id).Set<GpuSharedData*>();
|
||||
return ::mediapipe::OkStatus();
|
||||
return absl::OkStatus();
|
||||
}
|
||||
|
||||
::mediapipe::Status GlCalculatorHelper::RunInGlContext(
|
||||
std::function<::mediapipe::Status(void)> gl_func) {
|
||||
if (!impl_) return ::mediapipe::InternalError("helper not initialized");
|
||||
absl::Status GlCalculatorHelper::RunInGlContext(
|
||||
std::function<absl::Status(void)> gl_func) {
|
||||
if (!impl_) return absl::InternalError("helper not initialized");
|
||||
// TODO: Remove LegacyCalculatorSupport from MediaPipe OSS.
|
||||
auto calculator_context =
|
||||
LegacyCalculatorSupport::Scoped<CalculatorContext>::current();
|
||||
@@ -140,4 +141,21 @@ GlContext& GlCalculatorHelper::GetGlContext() const {
|
||||
return impl_->GetGlContext();
|
||||
}
|
||||
|
||||
GlVersion GlCalculatorHelper::GetGlVersion() const {
|
||||
return impl_->GetGlVersion();
|
||||
}
|
||||
|
||||
GlTexture GlCalculatorHelper::CreateSourceTexture(
|
||||
const mediapipe::Image& image) {
|
||||
return impl_->CreateSourceTexture(image.GetGpuBuffer());
|
||||
}
|
||||
|
||||
template <>
|
||||
std::unique_ptr<mediapipe::Image> GlTexture::GetFrame<mediapipe::Image>()
|
||||
const {
|
||||
std::unique_ptr<GpuBuffer> buf = GetFrame<GpuBuffer>();
|
||||
auto output = absl::make_unique<mediapipe::Image>(*buf);
|
||||
return output;
|
||||
}
|
||||
|
||||
} // namespace mediapipe
|
||||
|
||||
@@ -18,6 +18,7 @@
|
||||
#include "absl/memory/memory.h"
|
||||
#include "mediapipe/framework/calculator_context.h"
|
||||
#include "mediapipe/framework/calculator_contract.h"
|
||||
#include "mediapipe/framework/formats/image.h"
|
||||
#include "mediapipe/framework/formats/image_frame.h"
|
||||
#include "mediapipe/framework/packet.h"
|
||||
#include "mediapipe/framework/packet_set.h"
|
||||
@@ -68,7 +69,7 @@ class GlCalculatorHelper {
|
||||
~GlCalculatorHelper();
|
||||
|
||||
// Call Open from the Open method of a calculator to initialize the helper.
|
||||
::mediapipe::Status Open(CalculatorContext* cc);
|
||||
absl::Status Open(CalculatorContext* cc);
|
||||
|
||||
// Can be used to initialize the helper outside of a calculator. Useful for
|
||||
// testing.
|
||||
@@ -77,33 +78,31 @@ class GlCalculatorHelper {
|
||||
|
||||
// This method can be called from GetContract to set up the needed GPU
|
||||
// resources.
|
||||
static ::mediapipe::Status UpdateContract(CalculatorContract* cc);
|
||||
static absl::Status UpdateContract(CalculatorContract* cc);
|
||||
|
||||
// This method can be called from FillExpectations to set the correct types
|
||||
// for the shared GL input side packet(s).
|
||||
static ::mediapipe::Status SetupInputSidePackets(
|
||||
PacketTypeSet* input_side_packets);
|
||||
static absl::Status SetupInputSidePackets(PacketTypeSet* input_side_packets);
|
||||
|
||||
// Execute the provided function within the helper's GL context. On some
|
||||
// platforms, this may be run on a different thread; however, this method
|
||||
// will still wait for the function to finish executing before returning.
|
||||
// The status result from the function is passed on to the caller.
|
||||
::mediapipe::Status RunInGlContext(
|
||||
std::function<::mediapipe::Status(void)> gl_func);
|
||||
absl::Status RunInGlContext(std::function<absl::Status(void)> gl_func);
|
||||
|
||||
// Convenience version of RunInGlContext for arguments with a void result
|
||||
// type. As with the ::mediapipe::Status version, this also waits for the
|
||||
// type. As with the absl::Status version, this also waits for the
|
||||
// function to finish executing before returning.
|
||||
//
|
||||
// Implementation note: we cannot use a std::function<void(void)> argument
|
||||
// here, because that would break passing in a lambda that returns a status;
|
||||
// e.g.:
|
||||
// RunInGlContext([]() -> ::mediapipe::Status { ... });
|
||||
// RunInGlContext([]() -> absl::Status { ... });
|
||||
//
|
||||
// The reason is that std::function<void(...)> allows the implicit conversion
|
||||
// of a callable with any result type, as long as the argument types match.
|
||||
// As a result, the above lambda would be implicitly convertible to both
|
||||
// std::function<::mediapipe::Status(void)> and std::function<void(void)>, and
|
||||
// std::function<absl::Status(void)> and std::function<void(void)>, and
|
||||
// the invocation would be ambiguous.
|
||||
//
|
||||
// Therefore, instead of using std::function<void(void)>, we use a template
|
||||
@@ -113,7 +112,7 @@ class GlCalculatorHelper {
|
||||
void RunInGlContext(T f) {
|
||||
RunInGlContext([f] {
|
||||
f();
|
||||
return ::mediapipe::OkStatus();
|
||||
return absl::OkStatus();
|
||||
}).IgnoreError();
|
||||
}
|
||||
|
||||
@@ -125,6 +124,7 @@ class GlCalculatorHelper {
|
||||
// Creates a texture representing an input frame, and manages sync token.
|
||||
GlTexture CreateSourceTexture(const GpuBuffer& pixel_buffer);
|
||||
GlTexture CreateSourceTexture(const ImageFrame& image_frame);
|
||||
GlTexture CreateSourceTexture(const mediapipe::Image& image);
|
||||
|
||||
#ifdef __APPLE__
|
||||
// Creates a texture from a plane of a planar buffer.
|
||||
@@ -153,6 +153,8 @@ class GlCalculatorHelper {
|
||||
|
||||
GlContext& GetGlContext() const;
|
||||
|
||||
GlVersion GetGlVersion() const;
|
||||
|
||||
// Check if the calculator helper has been previously initialized.
|
||||
bool Initialized() { return impl_ != nullptr; }
|
||||
|
||||
|
||||
@@ -37,9 +37,8 @@ class GlCalculatorHelperImpl {
|
||||
GpuResources* gpu_resources);
|
||||
~GlCalculatorHelperImpl();
|
||||
|
||||
::mediapipe::Status RunInGlContext(
|
||||
std::function<::mediapipe::Status(void)> gl_func,
|
||||
CalculatorContext* calculator_context);
|
||||
absl::Status RunInGlContext(std::function<absl::Status(void)> gl_func,
|
||||
CalculatorContext* calculator_context);
|
||||
|
||||
GlTexture CreateSourceTexture(const ImageFrame& image_frame);
|
||||
GlTexture CreateSourceTexture(const GpuBuffer& gpu_buffer);
|
||||
@@ -54,9 +53,7 @@ class GlCalculatorHelperImpl {
|
||||
GLuint framebuffer() const { return framebuffer_; }
|
||||
void BindFramebuffer(const GlTexture& dst);
|
||||
|
||||
#ifdef __APPLE__
|
||||
GlVersion GetGlVersion();
|
||||
#endif
|
||||
GlVersion GetGlVersion() const { return gl_context_->GetGlVersion(); }
|
||||
|
||||
GlContext& GetGlContext() const;
|
||||
|
||||
|
||||
@@ -36,6 +36,15 @@ std::unique_ptr<ImageFrame> GlTexture::GetFrame<ImageFrame>() const {
|
||||
|
||||
template <>
|
||||
std::unique_ptr<GpuBuffer> GlTexture::GetFrame<GpuBuffer>() const {
|
||||
#ifdef __EMSCRIPTEN__
|
||||
// When WebGL is used, the GL context may be spontaneously lost which can
|
||||
// cause GpuBuffer allocations to fail. In that case, return a dummy buffer
|
||||
// to allow processing of the current frame complete.
|
||||
if (!gpu_buffer_) {
|
||||
return std::make_unique<GpuBuffer>();
|
||||
}
|
||||
#endif // __EMSCRIPTEN__
|
||||
|
||||
CHECK(gpu_buffer_);
|
||||
// Inform the GlTextureBuffer that we have produced new content, and create
|
||||
// a producer sync point.
|
||||
|
||||
@@ -42,7 +42,7 @@ GlCalculatorHelperImpl::~GlCalculatorHelperImpl() {
|
||||
glDeleteFramebuffers(1, &framebuffer_);
|
||||
framebuffer_ = 0;
|
||||
}
|
||||
return ::mediapipe::OkStatus();
|
||||
return absl::OkStatus();
|
||||
},
|
||||
/*calculator_context=*/nullptr)
|
||||
.IgnoreError();
|
||||
@@ -50,8 +50,8 @@ GlCalculatorHelperImpl::~GlCalculatorHelperImpl() {
|
||||
|
||||
GlContext& GlCalculatorHelperImpl::GetGlContext() const { return *gl_context_; }
|
||||
|
||||
::mediapipe::Status GlCalculatorHelperImpl::RunInGlContext(
|
||||
std::function<::mediapipe::Status(void)> gl_func,
|
||||
absl::Status GlCalculatorHelperImpl::RunInGlContext(
|
||||
std::function<absl::Status(void)> gl_func,
|
||||
CalculatorContext* calculator_context) {
|
||||
if (calculator_context) {
|
||||
return gl_context_->Run(std::move(gl_func), calculator_context->NodeId(),
|
||||
@@ -161,12 +161,14 @@ GlTexture GlCalculatorHelperImpl::MapGlTextureBuffer(
|
||||
texture.target_ = texture_buffer->target_;
|
||||
texture.name_ = texture_buffer->name_;
|
||||
|
||||
// TODO: do the params need to be reset here??
|
||||
glBindTexture(texture.target(), texture.name());
|
||||
GlTextureInfo info =
|
||||
GlTextureInfoForGpuBufferFormat(texture_buffer->format(), texture.plane_);
|
||||
SetStandardTextureParams(texture.target(), info.gl_internal_format);
|
||||
glBindTexture(texture.target(), 0);
|
||||
if (texture_buffer->format() != GpuBufferFormat::kUnknown) {
|
||||
// TODO: do the params need to be reset here??
|
||||
glBindTexture(texture.target(), texture.name());
|
||||
GlTextureInfo info = GlTextureInfoForGpuBufferFormat(
|
||||
texture_buffer->format(), texture.plane_, GetGlVersion());
|
||||
SetStandardTextureParams(texture.target(), info.gl_internal_format);
|
||||
glBindTexture(texture.target(), 0);
|
||||
}
|
||||
|
||||
return texture;
|
||||
}
|
||||
@@ -178,11 +180,14 @@ GlTextureBufferSharedPtr GlCalculatorHelperImpl::MakeGlTextureBuffer(
|
||||
image_frame.Width(), image_frame.Height(),
|
||||
GpuBufferFormatForImageFormat(image_frame.Format()),
|
||||
image_frame.PixelData());
|
||||
glBindTexture(GL_TEXTURE_2D, buffer->name_);
|
||||
GlTextureInfo info =
|
||||
GlTextureInfoForGpuBufferFormat(buffer->format_, /*plane=*/0);
|
||||
SetStandardTextureParams(buffer->target_, info.gl_internal_format);
|
||||
glBindTexture(GL_TEXTURE_2D, 0);
|
||||
|
||||
if (buffer->format_ != GpuBufferFormat::kUnknown) {
|
||||
glBindTexture(GL_TEXTURE_2D, buffer->name_);
|
||||
GlTextureInfo info = GlTextureInfoForGpuBufferFormat(
|
||||
buffer->format_, /*plane=*/0, GetGlVersion());
|
||||
SetStandardTextureParams(buffer->target_, info.gl_internal_format);
|
||||
glBindTexture(GL_TEXTURE_2D, 0);
|
||||
}
|
||||
|
||||
return buffer;
|
||||
}
|
||||
|
||||
@@ -28,15 +28,6 @@
|
||||
|
||||
namespace mediapipe {
|
||||
|
||||
GlVersion GlCalculatorHelperImpl::GetGlVersion() {
|
||||
#if TARGET_OS_OSX
|
||||
return GlVersion::kGL;
|
||||
#else
|
||||
if (gl_context_->eagl_context().API == kEAGLRenderingAPIOpenGLES3) return GlVersion::kGLES3;
|
||||
else return GlVersion::kGLES2;
|
||||
#endif // TARGET_OS_OSX
|
||||
}
|
||||
|
||||
#if MEDIAPIPE_GPU_BUFFER_USE_CV_PIXEL_BUFFER
|
||||
GlTexture GlCalculatorHelperImpl::CreateSourceTexture(
|
||||
const mediapipe::ImageFrame& image_frame) {
|
||||
@@ -122,9 +113,9 @@ std::unique_ptr<ImageFrame> GlTexture::GetFrame<ImageFrame>() const {
|
||||
|
||||
ImageFormat::Format image_format =
|
||||
ImageFormatForGpuBufferFormat(gpu_buffer_.format());
|
||||
// TODO: handle gl version here.
|
||||
GlTextureInfo info = GlTextureInfoForGpuBufferFormat(
|
||||
gpu_buffer_.format(), plane_);
|
||||
CHECK(helper_impl_);
|
||||
GlTextureInfo info =
|
||||
GlTextureInfoForGpuBufferFormat(gpu_buffer_.format(), plane_, helper_impl_->GetGlVersion());
|
||||
|
||||
auto output = absl::make_unique<ImageFrame>(
|
||||
image_format, width_, height_);
|
||||
|
||||
+40
-27
@@ -29,6 +29,7 @@
|
||||
#include "mediapipe/framework/port/status.h"
|
||||
#include "mediapipe/framework/port/status_builder.h"
|
||||
#include "mediapipe/gpu/gl_context_internal.h"
|
||||
#include "mediapipe/gpu/gpu_buffer_format.h"
|
||||
|
||||
#ifndef __EMSCRIPTEN__
|
||||
#include "absl/debugging/leak_check.h"
|
||||
@@ -140,13 +141,13 @@ void GlContext::DedicatedThread::ThreadBody() {
|
||||
#endif
|
||||
}
|
||||
|
||||
::mediapipe::Status GlContext::DedicatedThread::Run(GlStatusFunction gl_func) {
|
||||
absl::Status GlContext::DedicatedThread::Run(GlStatusFunction gl_func) {
|
||||
// Neither ENDO_SCOPE nor ENDO_TASK seem to work here.
|
||||
if (IsCurrentThread()) {
|
||||
return gl_func();
|
||||
}
|
||||
bool done = false; // Guarded by mutex_ after initialization.
|
||||
::mediapipe::Status status;
|
||||
absl::Status status;
|
||||
PutJob([this, gl_func, &done, &status]() {
|
||||
status = gl_func();
|
||||
absl::MutexLock lock(&mutex_);
|
||||
@@ -204,6 +205,14 @@ bool GlContext::ParseGlVersion(absl::string_view version_string, GLint* major,
|
||||
return true;
|
||||
}
|
||||
|
||||
GlVersion GlContext::GetGlVersion() const {
|
||||
#ifdef GL_ES_VERSION_2_0 // This actually means "is GLES available".
|
||||
return gl_major_version() < 3 ? GlVersion::kGLES2 : GlVersion::kGLES3;
|
||||
#else // This is the "desktop GL" case.
|
||||
return GlVersion::kGL;
|
||||
#endif
|
||||
}
|
||||
|
||||
bool GlContext::HasGlExtension(absl::string_view extension) const {
|
||||
return gl_extensions_.find(extension) != gl_extensions_.end();
|
||||
}
|
||||
@@ -212,7 +221,7 @@ bool GlContext::HasGlExtension(absl::string_view extension) const {
|
||||
// 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() {
|
||||
absl::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.
|
||||
@@ -226,54 +235,52 @@ bool GlContext::HasGlExtension(absl::string_view extension) const {
|
||||
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");
|
||||
return absl::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");
|
||||
return absl::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");
|
||||
return absl::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();
|
||||
return absl::OkStatus();
|
||||
#else
|
||||
return ::mediapipe::InternalError("GL version mismatch in GlGetExtensions");
|
||||
return absl::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() {
|
||||
absl::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");
|
||||
return absl::InternalError("Error querying for GL extensions");
|
||||
}
|
||||
const char* signed_res = reinterpret_cast<const char*>(res);
|
||||
gl_extensions_ = absl::StrSplit(signed_res, ' ');
|
||||
|
||||
return ::mediapipe::OkStatus();
|
||||
return absl::OkStatus();
|
||||
}
|
||||
|
||||
::mediapipe::Status GlContext::FinishInitialization(bool create_thread) {
|
||||
absl::Status GlContext::FinishInitialization(bool create_thread) {
|
||||
if (create_thread) {
|
||||
thread_ = absl::make_unique<GlContext::DedicatedThread>();
|
||||
MP_RETURN_IF_ERROR(thread_->Run([this] { return EnterContext(nullptr); }));
|
||||
}
|
||||
|
||||
return Run([this]() -> ::mediapipe::Status {
|
||||
return Run([this]() -> absl::Status {
|
||||
// Clear any GL errors at this point: as this is a fresh context
|
||||
// there shouldn't be any, but if we adopted an existing context (e.g. in
|
||||
// some Emscripten cases), there might be some existing tripped error.
|
||||
@@ -326,7 +333,7 @@ bool GlContext::HasGlExtension(absl::string_view extension) const {
|
||||
if (gl_major_version_ >= 3) {
|
||||
auto status = GetGlExtensions();
|
||||
if (status.ok()) {
|
||||
return ::mediapipe::OkStatus();
|
||||
return absl::OkStatus();
|
||||
}
|
||||
}
|
||||
return GetGlExtensionsCompat();
|
||||
@@ -368,7 +375,7 @@ void GlContext::SetProfilingContext(
|
||||
}
|
||||
}
|
||||
|
||||
::mediapipe::Status GlContext::SwitchContextAndRun(GlStatusFunction gl_func) {
|
||||
absl::Status GlContext::SwitchContextAndRun(GlStatusFunction gl_func) {
|
||||
ContextBinding saved_context;
|
||||
MP_RETURN_IF_ERROR(EnterContext(&saved_context)) << " (entering GL context)";
|
||||
auto status = gl_func();
|
||||
@@ -377,9 +384,9 @@ void GlContext::SetProfilingContext(
|
||||
return status;
|
||||
}
|
||||
|
||||
::mediapipe::Status GlContext::Run(GlStatusFunction gl_func, int node_id,
|
||||
Timestamp input_timestamp) {
|
||||
::mediapipe::Status status;
|
||||
absl::Status GlContext::Run(GlStatusFunction gl_func, int node_id,
|
||||
Timestamp input_timestamp) {
|
||||
absl::Status status;
|
||||
if (profiling_helper_) {
|
||||
gl_func = [=] {
|
||||
profiling_helper_->MarkTimestamp(node_id, input_timestamp,
|
||||
@@ -416,7 +423,7 @@ void GlContext::RunWithoutWaiting(GlVoidFunction gl_func) {
|
||||
// TODO: queue up task instead.
|
||||
auto status = SwitchContextAndRun([gl_func] {
|
||||
gl_func();
|
||||
return ::mediapipe::OkStatus();
|
||||
return absl::OkStatus();
|
||||
});
|
||||
if (!status.ok()) {
|
||||
LOG(ERROR) << "Error in RunWithoutWaiting: " << status;
|
||||
@@ -433,8 +440,8 @@ std::weak_ptr<GlContext>& GlContext::CurrentContext() {
|
||||
return current_context;
|
||||
}
|
||||
|
||||
::mediapipe::Status GlContext::SwitchContext(ContextBinding* saved_context,
|
||||
const ContextBinding& new_context)
|
||||
absl::Status GlContext::SwitchContext(ContextBinding* saved_context,
|
||||
const ContextBinding& new_context)
|
||||
ABSL_NO_THREAD_SAFETY_ANALYSIS {
|
||||
std::shared_ptr<GlContext> old_context_obj = CurrentContext().lock();
|
||||
std::shared_ptr<GlContext> new_context_obj =
|
||||
@@ -452,7 +459,7 @@ std::weak_ptr<GlContext>& GlContext::CurrentContext() {
|
||||
}
|
||||
|
||||
if (new_context_obj && (old_context_obj == new_context_obj)) {
|
||||
return ::mediapipe::OkStatus();
|
||||
return absl::OkStatus();
|
||||
}
|
||||
|
||||
if (old_context_obj) {
|
||||
@@ -479,13 +486,12 @@ std::weak_ptr<GlContext>& GlContext::CurrentContext() {
|
||||
}
|
||||
}
|
||||
|
||||
::mediapipe::Status GlContext::EnterContext(ContextBinding* saved_context) {
|
||||
absl::Status GlContext::EnterContext(ContextBinding* saved_context) {
|
||||
DCHECK(HasContext());
|
||||
return SwitchContext(saved_context, ThisContextBinding());
|
||||
}
|
||||
|
||||
::mediapipe::Status GlContext::ExitContext(
|
||||
const ContextBinding* saved_context) {
|
||||
absl::Status GlContext::ExitContext(const ContextBinding* saved_context) {
|
||||
ContextBinding no_context;
|
||||
if (!saved_context) {
|
||||
saved_context = &no_context;
|
||||
@@ -822,4 +828,11 @@ void GlContext::LogUncheckedGlErrors(bool had_gl_errors) {
|
||||
}
|
||||
}
|
||||
|
||||
const GlTextureInfo& GlTextureInfoForGpuBufferFormat(GpuBufferFormat format,
|
||||
int plane) {
|
||||
std::shared_ptr<GlContext> ctx = GlContext::GetCurrent();
|
||||
CHECK(ctx != nullptr);
|
||||
return GlTextureInfoForGpuBufferFormat(format, plane, ctx->GetGlVersion());
|
||||
}
|
||||
|
||||
} // namespace mediapipe
|
||||
|
||||
+34
-25
@@ -29,6 +29,7 @@
|
||||
#include "mediapipe/framework/port/threadpool.h"
|
||||
#include "mediapipe/framework/timestamp.h"
|
||||
#include "mediapipe/gpu/gl_base.h"
|
||||
#include "mediapipe/gpu/gpu_buffer_format.h"
|
||||
|
||||
#ifdef __APPLE__
|
||||
#include <CoreVideo/CoreVideo.h>
|
||||
@@ -64,7 +65,7 @@ struct EAGLContext;
|
||||
namespace mediapipe {
|
||||
|
||||
typedef std::function<void()> GlVoidFunction;
|
||||
typedef std::function<::mediapipe::Status()> GlStatusFunction;
|
||||
typedef std::function<absl::Status()> GlStatusFunction;
|
||||
|
||||
class GlContext;
|
||||
|
||||
@@ -141,10 +142,9 @@ constexpr PlatformGlContext kPlatformGlContextNone = nil;
|
||||
// - Managing the interaction between threads and GL contexts.
|
||||
// - Managing synchronization between different GL contexts.
|
||||
//
|
||||
// See go/mediapipe-gl-context for details.
|
||||
class GlContext : public std::enable_shared_from_this<GlContext> {
|
||||
public:
|
||||
using StatusOrGlContext = ::mediapipe::StatusOr<std::shared_ptr<GlContext>>;
|
||||
using StatusOrGlContext = absl::StatusOr<std::shared_ptr<GlContext>>;
|
||||
// Creates a GlContext.
|
||||
//
|
||||
// The first argument (which can be a GlContext, or a platform-specific type)
|
||||
@@ -180,8 +180,8 @@ class GlContext : public std::enable_shared_from_this<GlContext> {
|
||||
|
||||
// Executes a function in the GL context. Waits for the
|
||||
// function's execution to be complete before returning to the caller.
|
||||
::mediapipe::Status Run(GlStatusFunction gl_func, int node_id = -1,
|
||||
Timestamp input_timestamp = Timestamp::Unset());
|
||||
absl::Status Run(GlStatusFunction gl_func, int node_id = -1,
|
||||
Timestamp input_timestamp = Timestamp::Unset());
|
||||
|
||||
// Like Run, but does not wait.
|
||||
void RunWithoutWaiting(GlVoidFunction gl_func);
|
||||
@@ -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);
|
||||
|
||||
// Returns a GlVersion code used with GpuBufferFormat.
|
||||
// TODO: make this more generally applicable.
|
||||
GlVersion GetGlVersion() const;
|
||||
|
||||
// Simple query for GL extension support; only valid after GlContext has
|
||||
// finished its initialization successfully.
|
||||
bool HasGlExtension(absl::string_view extension) const;
|
||||
@@ -253,12 +257,12 @@ class GlContext : public std::enable_shared_from_this<GlContext> {
|
||||
// Implementation note: we cannot use a std::function<void(void)> argument
|
||||
// here, because that would break passing in a lambda that returns a status;
|
||||
// e.g.:
|
||||
// RunInGlContext([]() -> ::mediapipe::Status { ... });
|
||||
// RunInGlContext([]() -> absl::Status { ... });
|
||||
//
|
||||
// The reason is that std::function<void(...)> allows the implicit conversion
|
||||
// of a callable with any result type, as long as the argument types match.
|
||||
// As a result, the above lambda would be implicitly convertible to both
|
||||
// std::function<::mediapipe::Status(void)> and std::function<void(void)>, and
|
||||
// std::function<absl::Status(void)> and std::function<void(void)>, and
|
||||
// the invocation would be ambiguous.
|
||||
//
|
||||
// Therefore, instead of using std::function<void(void)>, we use a template
|
||||
@@ -268,7 +272,7 @@ class GlContext : public std::enable_shared_from_this<GlContext> {
|
||||
void Run(T f) {
|
||||
Run([f] {
|
||||
f();
|
||||
return ::mediapipe::OkStatus();
|
||||
return absl::OkStatus();
|
||||
}).IgnoreError();
|
||||
}
|
||||
|
||||
@@ -284,29 +288,27 @@ class GlContext : public std::enable_shared_from_this<GlContext> {
|
||||
GlContext();
|
||||
|
||||
#if defined(__EMSCRIPTEN__)
|
||||
::mediapipe::Status CreateContext(
|
||||
EMSCRIPTEN_WEBGL_CONTEXT_HANDLE share_context);
|
||||
::mediapipe::Status CreateContextInternal(
|
||||
absl::Status CreateContext(EMSCRIPTEN_WEBGL_CONTEXT_HANDLE share_context);
|
||||
absl::Status CreateContextInternal(
|
||||
EMSCRIPTEN_WEBGL_CONTEXT_HANDLE share_context, int webgl_version);
|
||||
|
||||
EMSCRIPTEN_WEBGL_CONTEXT_HANDLE context_ = 0;
|
||||
EmscriptenWebGLContextAttributes attrs_;
|
||||
#elif HAS_EGL
|
||||
::mediapipe::Status CreateContext(EGLContext share_context);
|
||||
::mediapipe::Status CreateContextInternal(EGLContext share_context,
|
||||
int gl_version);
|
||||
absl::Status CreateContext(EGLContext share_context);
|
||||
absl::Status CreateContextInternal(EGLContext share_context, int gl_version);
|
||||
|
||||
EGLDisplay display_ = EGL_NO_DISPLAY;
|
||||
EGLConfig config_;
|
||||
EGLSurface surface_ = EGL_NO_SURFACE;
|
||||
EGLContext context_ = EGL_NO_CONTEXT;
|
||||
#elif HAS_EAGL
|
||||
::mediapipe::Status CreateContext(EAGLSharegroup* sharegroup);
|
||||
absl::Status CreateContext(EAGLSharegroup* sharegroup);
|
||||
|
||||
EAGLContext* context_;
|
||||
CFHolder<CVOpenGLESTextureCacheRef> texture_cache_;
|
||||
#elif HAS_NSGL
|
||||
::mediapipe::Status CreateContext(NSOpenGLContext* share_context);
|
||||
absl::Status CreateContext(NSOpenGLContext* share_context);
|
||||
|
||||
NSOpenGLContext* context_;
|
||||
NSOpenGLPixelFormat* pixel_format_;
|
||||
@@ -335,16 +337,16 @@ class GlContext : public std::enable_shared_from_this<GlContext> {
|
||||
#endif // HAS_EGL
|
||||
};
|
||||
|
||||
::mediapipe::Status FinishInitialization(bool create_thread);
|
||||
absl::Status FinishInitialization(bool create_thread);
|
||||
|
||||
// This wraps a thread_local.
|
||||
static std::weak_ptr<GlContext>& CurrentContext();
|
||||
|
||||
static ::mediapipe::Status SwitchContext(ContextBinding* old_context,
|
||||
const ContextBinding& new_context);
|
||||
static absl::Status SwitchContext(ContextBinding* old_context,
|
||||
const ContextBinding& new_context);
|
||||
|
||||
::mediapipe::Status EnterContext(ContextBinding* previous_context);
|
||||
::mediapipe::Status ExitContext(const ContextBinding* previous_context);
|
||||
absl::Status EnterContext(ContextBinding* previous_context);
|
||||
absl::Status ExitContext(const ContextBinding* previous_context);
|
||||
void DestroyContext();
|
||||
|
||||
bool HasContext() const;
|
||||
@@ -363,13 +365,13 @@ class GlContext : public std::enable_shared_from_this<GlContext> {
|
||||
bool CheckForGlErrors(bool force);
|
||||
|
||||
void LogUncheckedGlErrors(bool had_gl_errors);
|
||||
::mediapipe::Status GetGlExtensions();
|
||||
::mediapipe::Status GetGlExtensionsCompat();
|
||||
absl::Status GetGlExtensions();
|
||||
absl::Status GetGlExtensionsCompat();
|
||||
|
||||
// Make the context current, run gl_func, and restore the previous context.
|
||||
// Internal helper only; callers should use Run or RunWithoutWaiting instead,
|
||||
// which delegates to the dedicated thread if required.
|
||||
::mediapipe::Status SwitchContextAndRun(GlStatusFunction gl_func);
|
||||
absl::Status SwitchContextAndRun(GlStatusFunction gl_func);
|
||||
|
||||
// The following ContextBinding functions have platform-specific
|
||||
// implementations.
|
||||
@@ -380,7 +382,7 @@ class GlContext : public std::enable_shared_from_this<GlContext> {
|
||||
// context is current on this thread.
|
||||
static void GetCurrentContextBinding(ContextBinding* binding);
|
||||
// Makes the context described by new_context current on this thread.
|
||||
static ::mediapipe::Status SetCurrentContextBinding(
|
||||
static absl::Status SetCurrentContextBinding(
|
||||
const ContextBinding& new_context);
|
||||
|
||||
// If not null, a dedicated thread used to execute tasks on this context.
|
||||
@@ -415,5 +417,12 @@ class GlContext : public std::enable_shared_from_this<GlContext> {
|
||||
std::unique_ptr<mediapipe::GlProfilingHelper> profiling_helper_ = nullptr;
|
||||
};
|
||||
|
||||
// For backward compatibility. TODO: migrate remaining callers.
|
||||
ABSL_DEPRECATED(
|
||||
"Prefer passing an explicit GlVersion argument (use "
|
||||
"GlContext::GetGlVersion)")
|
||||
const GlTextureInfo& GlTextureInfoForGpuBufferFormat(GpuBufferFormat format,
|
||||
int plane);
|
||||
|
||||
} // namespace mediapipe
|
||||
#endif // MEDIAPIPE_GPU_GL_CONTEXT_H_
|
||||
|
||||
@@ -53,7 +53,7 @@ GlContext::StatusOrGlContext GlContext::Create(EAGLSharegroup* sharegroup,
|
||||
return std::move(context);
|
||||
}
|
||||
|
||||
::mediapipe::Status GlContext::CreateContext(EAGLSharegroup* sharegroup) {
|
||||
absl::Status GlContext::CreateContext(EAGLSharegroup* sharegroup) {
|
||||
context_ = [[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES3
|
||||
sharegroup:sharegroup];
|
||||
if (context_) {
|
||||
@@ -72,7 +72,7 @@ GlContext::StatusOrGlContext GlContext::Create(EAGLSharegroup* sharegroup,
|
||||
<< "Error at CVOpenGLESTextureCacheCreate";
|
||||
texture_cache_.adopt(cache);
|
||||
|
||||
return ::mediapipe::OkStatus();
|
||||
return absl::OkStatus();
|
||||
}
|
||||
|
||||
void GlContext::DestroyContext() {
|
||||
@@ -95,11 +95,11 @@ void GlContext::GetCurrentContextBinding(GlContext::ContextBinding* binding) {
|
||||
binding->context = [EAGLContext currentContext];
|
||||
}
|
||||
|
||||
::mediapipe::Status GlContext::SetCurrentContextBinding(
|
||||
absl::Status GlContext::SetCurrentContextBinding(
|
||||
const ContextBinding& new_binding) {
|
||||
BOOL success = [EAGLContext setCurrentContext:new_binding.context];
|
||||
RET_CHECK(success) << "Cannot set OpenGL context";
|
||||
return ::mediapipe::OkStatus();
|
||||
return absl::OkStatus();
|
||||
}
|
||||
|
||||
bool GlContext::HasContext() const { return context_ != nil; }
|
||||
|
||||
@@ -85,8 +85,8 @@ GlContext::StatusOrGlContext GlContext::Create(EGLContext share_context,
|
||||
return std::move(context);
|
||||
}
|
||||
|
||||
::mediapipe::Status GlContext::CreateContextInternal(
|
||||
EGLContext external_context, int gl_version) {
|
||||
absl::Status GlContext::CreateContextInternal(EGLContext external_context,
|
||||
int gl_version) {
|
||||
CHECK(gl_version == 2 || gl_version == 3);
|
||||
|
||||
const EGLint config_attr[] = {
|
||||
@@ -146,10 +146,10 @@ GlContext::StatusOrGlContext GlContext::Create(EGLContext share_context,
|
||||
// GLES 2 does not have them, so let's set the major version here at least.
|
||||
gl_major_version_ = gl_version;
|
||||
|
||||
return ::mediapipe::OkStatus();
|
||||
return absl::OkStatus();
|
||||
}
|
||||
|
||||
::mediapipe::Status GlContext::CreateContext(EGLContext external_context) {
|
||||
absl::Status GlContext::CreateContext(EGLContext external_context) {
|
||||
EGLint major = 0;
|
||||
EGLint minor = 0;
|
||||
|
||||
@@ -178,7 +178,7 @@ GlContext::StatusOrGlContext GlContext::Create(EGLContext share_context,
|
||||
<< "eglCreatePbufferSurface() returned error " << std::showbase
|
||||
<< std::hex << eglGetError();
|
||||
|
||||
return ::mediapipe::OkStatus();
|
||||
return absl::OkStatus();
|
||||
}
|
||||
|
||||
void GlContext::DestroyContext() {
|
||||
@@ -212,7 +212,7 @@ void GlContext::DestroyContext() {
|
||||
thread_
|
||||
->Run([] {
|
||||
eglReleaseThread();
|
||||
return ::mediapipe::OkStatus();
|
||||
return absl::OkStatus();
|
||||
})
|
||||
.IgnoreError();
|
||||
}
|
||||
@@ -271,7 +271,7 @@ void GlContext::GetCurrentContextBinding(GlContext::ContextBinding* binding) {
|
||||
binding->context = eglGetCurrentContext();
|
||||
}
|
||||
|
||||
::mediapipe::Status GlContext::SetCurrentContextBinding(
|
||||
absl::Status GlContext::SetCurrentContextBinding(
|
||||
const ContextBinding& new_binding) {
|
||||
EnsureEglThreadRelease();
|
||||
EGLDisplay display = new_binding.display;
|
||||
@@ -286,7 +286,7 @@ void GlContext::GetCurrentContextBinding(GlContext::ContextBinding* binding) {
|
||||
new_binding.read_surface, new_binding.context);
|
||||
RET_CHECK(success) << "eglMakeCurrent() returned error " << std::showbase
|
||||
<< std::hex << eglGetError();
|
||||
return ::mediapipe::OkStatus();
|
||||
return absl::OkStatus();
|
||||
}
|
||||
|
||||
bool GlContext::HasContext() const { return context_ != EGL_NO_CONTEXT; }
|
||||
|
||||
@@ -35,7 +35,7 @@ class GlContext::DedicatedThread {
|
||||
DedicatedThread(const DedicatedThread&) = delete;
|
||||
DedicatedThread& operator=(DedicatedThread) = delete;
|
||||
|
||||
::mediapipe::Status Run(GlStatusFunction gl_func);
|
||||
absl::Status Run(GlStatusFunction gl_func);
|
||||
void RunWithoutWaiting(GlVoidFunction gl_fund);
|
||||
|
||||
bool IsCurrentThread();
|
||||
|
||||
@@ -44,7 +44,7 @@ GlContext::StatusOrGlContext GlContext::Create(NSOpenGLContext* share_context,
|
||||
return std::move(context);
|
||||
}
|
||||
|
||||
::mediapipe::Status GlContext::CreateContext(NSOpenGLContext* share_context) {
|
||||
absl::Status GlContext::CreateContext(NSOpenGLContext* share_context) {
|
||||
// TODO: choose a better list?
|
||||
NSOpenGLPixelFormatAttribute attrs[] = {
|
||||
// This is required to get any OpenGL version 3.2 or higher. Note that
|
||||
@@ -96,8 +96,7 @@ GlContext::StatusOrGlContext GlContext::Create(NSOpenGLContext* share_context,
|
||||
[[NSOpenGLPixelFormat alloc] initWithAttributes:attrs_no_accel];
|
||||
}
|
||||
if (!pixel_format_)
|
||||
return ::mediapipe::InternalError(
|
||||
"Could not create an NSOpenGLPixelFormat");
|
||||
return absl::InternalError("Could not create an NSOpenGLPixelFormat");
|
||||
context_ = [[NSOpenGLContext alloc] initWithFormat:pixel_format_
|
||||
shareContext:share_context];
|
||||
|
||||
@@ -123,7 +122,7 @@ GlContext::StatusOrGlContext GlContext::Create(NSOpenGLContext* share_context,
|
||||
RET_CHECK_EQ(err, kCVReturnSuccess) << "Error at CVOpenGLTextureCacheCreate";
|
||||
texture_cache_.adopt(cache);
|
||||
|
||||
return ::mediapipe::OkStatus();
|
||||
return absl::OkStatus();
|
||||
}
|
||||
|
||||
void GlContext::DestroyContext() {
|
||||
@@ -146,14 +145,14 @@ void GlContext::GetCurrentContextBinding(GlContext::ContextBinding* binding) {
|
||||
binding->context = [NSOpenGLContext currentContext];
|
||||
}
|
||||
|
||||
::mediapipe::Status GlContext::SetCurrentContextBinding(
|
||||
absl::Status GlContext::SetCurrentContextBinding(
|
||||
const ContextBinding& new_binding) {
|
||||
if (new_binding.context) {
|
||||
[new_binding.context makeCurrentContext];
|
||||
} else {
|
||||
[NSOpenGLContext clearCurrentContext];
|
||||
}
|
||||
return ::mediapipe::OkStatus();
|
||||
return absl::OkStatus();
|
||||
}
|
||||
|
||||
bool GlContext::HasContext() const { return context_ != nil; }
|
||||
|
||||
@@ -46,7 +46,7 @@ GlContext::StatusOrGlContext GlContext::Create(
|
||||
return std::move(context);
|
||||
}
|
||||
|
||||
::mediapipe::Status GlContext::CreateContextInternal(
|
||||
absl::Status GlContext::CreateContextInternal(
|
||||
EMSCRIPTEN_WEBGL_CONTEXT_HANDLE external_context, int webgl_version) {
|
||||
CHECK(webgl_version == 1 || webgl_version == 2);
|
||||
|
||||
@@ -58,9 +58,12 @@ GlContext::StatusOrGlContext GlContext::Create(
|
||||
attrs.majorVersion = webgl_version;
|
||||
attrs.minorVersion = 0;
|
||||
|
||||
attrs.premultipliedAlpha = 0;
|
||||
// New one to try out... TODO: see if actually necessary for
|
||||
// pushing resulting texture through MediaPipe pipeline.
|
||||
// This flag tells the page compositor that the image written to the canvas
|
||||
// uses premultiplied alpha, and so can be used directly for compositing.
|
||||
// Without this, it needs to make an additional full-canvas rendering pass.
|
||||
attrs.premultipliedAlpha = 1;
|
||||
|
||||
// TODO: Investigate this option in more detail, esp. on Safari.
|
||||
attrs.preserveDrawingBuffer = 0;
|
||||
|
||||
// Since the Emscripten canvas target finding function is visible from here,
|
||||
@@ -124,10 +127,10 @@ GlContext::StatusOrGlContext GlContext::Create(
|
||||
// GLES 2 does not have them, so let's set the major version here at least.
|
||||
// WebGL 1.0 maps to GLES 2.0 and WebGL 2.0 maps to GLES 3.0, so we add 1.
|
||||
gl_major_version_ = webgl_version + 1;
|
||||
return ::mediapipe::OkStatus();
|
||||
return absl::OkStatus();
|
||||
}
|
||||
|
||||
::mediapipe::Status GlContext::CreateContext(
|
||||
absl::Status GlContext::CreateContext(
|
||||
EMSCRIPTEN_WEBGL_CONTEXT_HANDLE external_context) {
|
||||
// TODO: If we're given a non-0 external_context, could try to use
|
||||
// that directly, since we're assuming a single-threaded single-context
|
||||
@@ -144,7 +147,7 @@ GlContext::StatusOrGlContext GlContext::Create(
|
||||
LOG(INFO) << "Successfully created a WebGL context with major version "
|
||||
<< gl_major_version_ << " and handle " << context_;
|
||||
|
||||
return ::mediapipe::OkStatus();
|
||||
return absl::OkStatus();
|
||||
}
|
||||
|
||||
void GlContext::DestroyContext() {
|
||||
@@ -177,13 +180,13 @@ void GlContext::GetCurrentContextBinding(GlContext::ContextBinding* binding) {
|
||||
binding->context = emscripten_webgl_get_current_context();
|
||||
}
|
||||
|
||||
::mediapipe::Status GlContext::SetCurrentContextBinding(
|
||||
absl::Status GlContext::SetCurrentContextBinding(
|
||||
const ContextBinding& new_binding) {
|
||||
if (new_binding.context == 0) {
|
||||
// Calling emscripten_webgl_make_context_current(0) is resulting in an error
|
||||
// so don't remove context for now, only replace! In the future, can
|
||||
// perhaps create a separate "do-nothing" context for this.
|
||||
return ::mediapipe::OkStatus();
|
||||
return absl::OkStatus();
|
||||
}
|
||||
// TODO: See if setting the same context to current multiple times
|
||||
// comes with a performance cost, and fix if so.
|
||||
@@ -191,7 +194,7 @@ void GlContext::GetCurrentContextBinding(GlContext::ContextBinding* binding) {
|
||||
emscripten_webgl_make_context_current(new_binding.context);
|
||||
RET_CHECK(res == EMSCRIPTEN_RESULT_SUCCESS)
|
||||
<< "emscripten_webgl_make_context_current() returned error " << res;
|
||||
return ::mediapipe::OkStatus();
|
||||
return absl::OkStatus();
|
||||
}
|
||||
|
||||
bool GlContext::HasContext() const { return context_ != 0; }
|
||||
|
||||
@@ -98,7 +98,7 @@
|
||||
|
||||
- (void)testGlConverters {
|
||||
CFHolder<CVPixelBufferRef> originalPixelBuffer;
|
||||
::mediapipe::Status status =
|
||||
absl::Status status =
|
||||
CreateCVPixelBufferFromCGImage([_sourceImage CGImage], &originalPixelBuffer);
|
||||
XCTAssert(status.ok());
|
||||
|
||||
@@ -121,7 +121,7 @@
|
||||
|
||||
- (void)testGlConvertersNoOpInserted {
|
||||
CFHolder<CVPixelBufferRef> originalPixelBuffer;
|
||||
::mediapipe::Status status =
|
||||
absl::Status status =
|
||||
CreateCVPixelBufferFromCGImage([_sourceImage CGImage], &originalPixelBuffer);
|
||||
XCTAssert(status.ok());
|
||||
|
||||
@@ -149,7 +149,7 @@
|
||||
|
||||
- (void)testGlConvertersWithOptionalSidePackets {
|
||||
CFHolder<CVPixelBufferRef> originalPixelBuffer;
|
||||
::mediapipe::Status status =
|
||||
absl::Status status =
|
||||
CreateCVPixelBufferFromCGImage([_sourceImage CGImage], &originalPixelBuffer);
|
||||
XCTAssert(status.ok());
|
||||
|
||||
@@ -191,7 +191,7 @@
|
||||
|
||||
- (void)testSimpleConversionFromFormat:(OSType)cvPixelFormat {
|
||||
CFHolder<CVPixelBufferRef> originalPixelBuffer;
|
||||
::mediapipe::Status status =
|
||||
absl::Status status =
|
||||
CreateCVPixelBufferFromCGImage([_sourceImage CGImage], &originalPixelBuffer);
|
||||
XCTAssert(status.ok());
|
||||
CVPixelBufferRef convertedPixelBuffer =
|
||||
@@ -225,7 +225,7 @@
|
||||
NSLog(@"Metal tests skipped on Simulator.");
|
||||
#else
|
||||
CFHolder<CVPixelBufferRef> originalPixelBuffer;
|
||||
::mediapipe::Status status =
|
||||
absl::Status status =
|
||||
CreateCVPixelBufferFromCGImage([_sourceImage CGImage], &originalPixelBuffer);
|
||||
XCTAssert(status.ok());
|
||||
CVPixelBufferRef redPixelBuffer = [self redPixelBuffer:*originalPixelBuffer];
|
||||
|
||||
@@ -54,11 +54,11 @@ FrameRotation FrameRotationFromDegrees(int degrees_ccw) {
|
||||
}
|
||||
}
|
||||
|
||||
::mediapipe::Status QuadRenderer::GlSetup() {
|
||||
absl::Status QuadRenderer::GlSetup() {
|
||||
return GlSetup(kBasicTexturedFragmentShader, {"video_frame"});
|
||||
}
|
||||
|
||||
::mediapipe::Status QuadRenderer::GlSetup(
|
||||
absl::Status QuadRenderer::GlSetup(
|
||||
const GLchar* custom_frag_shader,
|
||||
const std::vector<const GLchar*>& custom_frame_uniforms) {
|
||||
// Load vertex and fragment shaders
|
||||
@@ -87,7 +87,7 @@ FrameRotation FrameRotationFromDegrees(int degrees_ccw) {
|
||||
glGenVertexArrays(1, &vao_);
|
||||
glGenBuffers(2, vbo_);
|
||||
|
||||
return ::mediapipe::OkStatus();
|
||||
return absl::OkStatus();
|
||||
}
|
||||
|
||||
void QuadRenderer::GlTeardown() {
|
||||
@@ -106,10 +106,12 @@ void QuadRenderer::GlTeardown() {
|
||||
}
|
||||
}
|
||||
|
||||
::mediapipe::Status QuadRenderer::GlRender(
|
||||
float frame_width, float frame_height, float view_width, float view_height,
|
||||
FrameScaleMode scale_mode, FrameRotation rotation, bool flip_horizontal,
|
||||
bool flip_vertical, bool flip_texture) {
|
||||
absl::Status QuadRenderer::GlRender(float frame_width, float frame_height,
|
||||
float view_width, float view_height,
|
||||
FrameScaleMode scale_mode,
|
||||
FrameRotation rotation,
|
||||
bool flip_horizontal, bool flip_vertical,
|
||||
bool flip_texture) {
|
||||
RET_CHECK(program_) << "Must setup the program before rendering.";
|
||||
|
||||
glUseProgram(program_);
|
||||
@@ -195,15 +197,14 @@ void QuadRenderer::GlTeardown() {
|
||||
glBindBuffer(GL_ARRAY_BUFFER, 0);
|
||||
glBindVertexArray(0);
|
||||
|
||||
return ::mediapipe::OkStatus();
|
||||
return absl::OkStatus();
|
||||
}
|
||||
|
||||
::mediapipe::Status FrameRotationFromInt(FrameRotation* rotation,
|
||||
int degrees_ccw) {
|
||||
absl::Status FrameRotationFromInt(FrameRotation* rotation, int degrees_ccw) {
|
||||
RET_CHECK(degrees_ccw % 90 == 0) << "rotation must be a multiple of 90; "
|
||||
<< degrees_ccw << " was provided";
|
||||
*rotation = FrameRotationFromDegrees(degrees_ccw % 360);
|
||||
return ::mediapipe::OkStatus();
|
||||
return absl::OkStatus();
|
||||
}
|
||||
|
||||
} // namespace mediapipe
|
||||
|
||||
@@ -49,13 +49,12 @@ class QuadRenderer {
|
||||
QuadRenderer() {}
|
||||
// Creates the rendering program. Must be called within the GL context that
|
||||
// will be used for rendering.
|
||||
::mediapipe::Status GlSetup();
|
||||
absl::Status GlSetup();
|
||||
// Creates the rendering program. Must be called within the GL context that
|
||||
// will be used for rendering.
|
||||
// This version allows you to customize the fragment shader.
|
||||
::mediapipe::Status GlSetup(
|
||||
const GLchar* custom_frag_shader,
|
||||
const std::vector<const GLchar*>& custom_frame_uniforms);
|
||||
absl::Status GlSetup(const GLchar* custom_frag_shader,
|
||||
const std::vector<const GLchar*>& custom_frame_uniforms);
|
||||
// Renders the texture bound to texture unit 1 onto the current viewport.
|
||||
// Note: mirroring and flipping are handled differently, by design.
|
||||
// - flip_texture is meant to be used when the texture image's rows are stored
|
||||
@@ -70,11 +69,10 @@ class QuadRenderer {
|
||||
// what's needed for the front-camera use case.
|
||||
// - flip_vertical is meant to be used to flip the output image vertically.
|
||||
// This flipping is applied AFTER rotation.
|
||||
::mediapipe::Status GlRender(float frame_width, float frame_height,
|
||||
float view_width, float view_height,
|
||||
FrameScaleMode scale_mode,
|
||||
FrameRotation rotation, bool flip_horizontal,
|
||||
bool flip_vertical, bool flip_texture);
|
||||
absl::Status GlRender(float frame_width, float frame_height, float view_width,
|
||||
float view_height, FrameScaleMode scale_mode,
|
||||
FrameRotation rotation, bool flip_horizontal,
|
||||
bool flip_vertical, bool flip_texture);
|
||||
// Deletes the rendering program. Must be called withn the GL context where
|
||||
// it was created.
|
||||
void GlTeardown();
|
||||
@@ -87,8 +85,7 @@ class QuadRenderer {
|
||||
GLuint vbo_[2] = {0, 0}; // for vertex buffer storage
|
||||
};
|
||||
|
||||
::mediapipe::Status FrameRotationFromInt(FrameRotation* rotation,
|
||||
int degrees_ccw);
|
||||
absl::Status FrameRotationFromInt(FrameRotation* rotation, int degrees_ccw);
|
||||
|
||||
// Input degrees must be one of: [0, 90, 180, 270].
|
||||
FrameRotation FrameRotationFromDegrees(int degrees_ccw);
|
||||
|
||||
@@ -66,13 +66,13 @@ class GlScalerCalculator : public CalculatorBase {
|
||||
GlScalerCalculator() {}
|
||||
~GlScalerCalculator();
|
||||
|
||||
static ::mediapipe::Status GetContract(CalculatorContract* cc);
|
||||
static absl::Status GetContract(CalculatorContract* cc);
|
||||
|
||||
::mediapipe::Status Open(CalculatorContext* cc) override;
|
||||
::mediapipe::Status Process(CalculatorContext* cc) override;
|
||||
absl::Status Open(CalculatorContext* cc) override;
|
||||
absl::Status Process(CalculatorContext* cc) override;
|
||||
|
||||
::mediapipe::Status GlSetup();
|
||||
::mediapipe::Status GlRender(const GlTexture& src, const GlTexture& dst);
|
||||
absl::Status GlSetup();
|
||||
absl::Status GlRender(const GlTexture& src, const GlTexture& dst);
|
||||
void GetOutputDimensions(int src_width, int src_height, int* dst_width,
|
||||
int* dst_height);
|
||||
void GetOutputPadding(int src_width, int src_height, int dst_width,
|
||||
@@ -98,7 +98,7 @@ class GlScalerCalculator : public CalculatorBase {
|
||||
REGISTER_CALCULATOR(GlScalerCalculator);
|
||||
|
||||
// static
|
||||
::mediapipe::Status GlScalerCalculator::GetContract(CalculatorContract* cc) {
|
||||
absl::Status GlScalerCalculator::GetContract(CalculatorContract* cc) {
|
||||
TagOrIndex(&cc->Inputs(), "VIDEO", 0).Set<GpuBuffer>();
|
||||
TagOrIndex(&cc->Outputs(), "VIDEO", 0).Set<GpuBuffer>();
|
||||
if (cc->Inputs().HasTag("ROTATION")) {
|
||||
@@ -126,10 +126,10 @@ REGISTER_CALCULATOR(GlScalerCalculator);
|
||||
cc->Outputs().Tag("TOP_BOTTOM_PADDING").Set<float>();
|
||||
cc->Outputs().Tag("LEFT_RIGHT_PADDING").Set<float>();
|
||||
}
|
||||
return ::mediapipe::OkStatus();
|
||||
return absl::OkStatus();
|
||||
}
|
||||
|
||||
::mediapipe::Status GlScalerCalculator::Open(CalculatorContext* cc) {
|
||||
absl::Status GlScalerCalculator::Open(CalculatorContext* cc) {
|
||||
// Inform the framework that we always output at the same timestamp
|
||||
// as we receive a packet at.
|
||||
cc->SetOffset(mediapipe::TimestampDiff(0));
|
||||
@@ -181,14 +181,14 @@ REGISTER_CALCULATOR(GlScalerCalculator);
|
||||
|
||||
MP_RETURN_IF_ERROR(FrameRotationFromInt(&rotation_, rotation_ccw));
|
||||
|
||||
return ::mediapipe::OkStatus();
|
||||
return absl::OkStatus();
|
||||
}
|
||||
|
||||
::mediapipe::Status GlScalerCalculator::Process(CalculatorContext* cc) {
|
||||
absl::Status GlScalerCalculator::Process(CalculatorContext* cc) {
|
||||
if (cc->Inputs().HasTag("OUTPUT_DIMENSIONS")) {
|
||||
if (cc->Inputs().Tag("OUTPUT_DIMENSIONS").IsEmpty()) {
|
||||
// OUTPUT_DIMENSIONS input stream is specified, but value is missing.
|
||||
return ::mediapipe::OkStatus();
|
||||
return absl::OkStatus();
|
||||
}
|
||||
|
||||
const auto& dimensions =
|
||||
@@ -197,7 +197,7 @@ REGISTER_CALCULATOR(GlScalerCalculator);
|
||||
dst_height_ = dimensions[1];
|
||||
}
|
||||
|
||||
return helper_.RunInGlContext([this, cc]() -> ::mediapipe::Status {
|
||||
return helper_.RunInGlContext([this, cc]() -> absl::Status {
|
||||
const auto& input = TagOrIndex(cc->Inputs(), "VIDEO", 0).Get<GpuBuffer>();
|
||||
QuadRenderer* renderer = nullptr;
|
||||
GlTexture src1;
|
||||
@@ -294,7 +294,7 @@ REGISTER_CALCULATOR(GlScalerCalculator);
|
||||
TagOrIndex(&cc->Outputs(), "VIDEO", 0)
|
||||
.Add(output.release(), cc->InputTimestamp());
|
||||
|
||||
return ::mediapipe::OkStatus();
|
||||
return absl::OkStatus();
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
namespace mediapipe {
|
||||
|
||||
// static
|
||||
::mediapipe::Status GlSimpleCalculator::GetContract(CalculatorContract* cc) {
|
||||
absl::Status GlSimpleCalculator::GetContract(CalculatorContract* cc) {
|
||||
TagOrIndex(&cc->Inputs(), "VIDEO", 0).Set<GpuBuffer>();
|
||||
TagOrIndex(&cc->Outputs(), "VIDEO", 0).Set<GpuBuffer>();
|
||||
// Currently we pass GL context information and other stuff as external
|
||||
@@ -25,7 +25,7 @@ namespace mediapipe {
|
||||
return GlCalculatorHelper::UpdateContract(cc);
|
||||
}
|
||||
|
||||
::mediapipe::Status GlSimpleCalculator::Open(CalculatorContext* cc) {
|
||||
absl::Status GlSimpleCalculator::Open(CalculatorContext* cc) {
|
||||
// Inform the framework that we always output at the same timestamp
|
||||
// as we receive a packet at.
|
||||
cc->SetOffset(mediapipe::TimestampDiff(0));
|
||||
@@ -34,8 +34,8 @@ namespace mediapipe {
|
||||
return helper_.Open(cc);
|
||||
}
|
||||
|
||||
::mediapipe::Status GlSimpleCalculator::Process(CalculatorContext* cc) {
|
||||
return RunInGlContext([this, cc]() -> ::mediapipe::Status {
|
||||
absl::Status GlSimpleCalculator::Process(CalculatorContext* cc) {
|
||||
return RunInGlContext([this, cc]() -> absl::Status {
|
||||
const auto& input = TagOrIndex(cc->Inputs(), "VIDEO", 0).Get<GpuBuffer>();
|
||||
if (!initialized_) {
|
||||
MP_RETURN_IF_ERROR(GlSetup());
|
||||
@@ -69,13 +69,12 @@ namespace mediapipe {
|
||||
TagOrIndex(&cc->Outputs(), "VIDEO", 0)
|
||||
.Add(output.release(), cc->InputTimestamp());
|
||||
|
||||
return ::mediapipe::OkStatus();
|
||||
return absl::OkStatus();
|
||||
});
|
||||
}
|
||||
|
||||
::mediapipe::Status GlSimpleCalculator::Close(CalculatorContext* cc) {
|
||||
return RunInGlContext(
|
||||
[this]() -> ::mediapipe::Status { return GlTeardown(); });
|
||||
absl::Status GlSimpleCalculator::Close(CalculatorContext* cc) {
|
||||
return RunInGlContext([this]() -> absl::Status { return GlTeardown(); });
|
||||
}
|
||||
|
||||
} // namespace mediapipe
|
||||
|
||||
@@ -53,30 +53,29 @@ class GlSimpleCalculator : public CalculatorBase {
|
||||
GlSimpleCalculator& operator=(const GlSimpleCalculator&) = delete;
|
||||
~GlSimpleCalculator() override = default;
|
||||
|
||||
static ::mediapipe::Status GetContract(CalculatorContract* cc);
|
||||
::mediapipe::Status Open(CalculatorContext* cc) override;
|
||||
::mediapipe::Status Process(CalculatorContext* cc) override;
|
||||
::mediapipe::Status Close(CalculatorContext* cc) override;
|
||||
static absl::Status GetContract(CalculatorContract* cc);
|
||||
absl::Status Open(CalculatorContext* cc) override;
|
||||
absl::Status Process(CalculatorContext* cc) override;
|
||||
absl::Status Close(CalculatorContext* cc) override;
|
||||
|
||||
// This method is called once on the first frame. Use it to setup any objects
|
||||
// that will be reused throughout the calculator's life.
|
||||
virtual ::mediapipe::Status GlSetup() = 0;
|
||||
virtual absl::Status GlSetup() = 0;
|
||||
|
||||
// You can use this optional method to do any pre-rendering setup that needs
|
||||
// to be redone after the context has been used by another calculator.
|
||||
// If your context is not shared, it will only be called once.
|
||||
virtual ::mediapipe::Status GlBind() { return ::mediapipe::OkStatus(); }
|
||||
virtual absl::Status GlBind() { return absl::OkStatus(); }
|
||||
|
||||
// Do your rendering here. The source and destination textures have already
|
||||
// been created and bound for you.
|
||||
// - src: source texture (contains input frame); already bound to GL_TEXTURE1.
|
||||
// - dst: destination texture (write output frame here); already bound to
|
||||
// GL_TEXTURE0 and attached to the framebuffer.
|
||||
virtual ::mediapipe::Status GlRender(const GlTexture& src,
|
||||
const GlTexture& dst) = 0;
|
||||
virtual absl::Status GlRender(const GlTexture& src, const GlTexture& dst) = 0;
|
||||
|
||||
// The method is called to delete all the programs.
|
||||
virtual ::mediapipe::Status GlTeardown() = 0;
|
||||
virtual absl::Status GlTeardown() = 0;
|
||||
|
||||
// You can override this method to compute the size of the destination
|
||||
// texture. By default, it will take the same size as the source texture.
|
||||
|
||||
@@ -42,10 +42,10 @@ class GlSurfaceSinkCalculator : public CalculatorBase {
|
||||
GlSurfaceSinkCalculator() : initialized_(false) {}
|
||||
~GlSurfaceSinkCalculator() override;
|
||||
|
||||
static ::mediapipe::Status GetContract(CalculatorContract* cc);
|
||||
static absl::Status GetContract(CalculatorContract* cc);
|
||||
|
||||
::mediapipe::Status Open(CalculatorContext* cc) override;
|
||||
::mediapipe::Status Process(CalculatorContext* cc) override;
|
||||
absl::Status Open(CalculatorContext* cc) override;
|
||||
absl::Status Process(CalculatorContext* cc) override;
|
||||
|
||||
private:
|
||||
GlCalculatorHelper helper_;
|
||||
@@ -57,8 +57,7 @@ class GlSurfaceSinkCalculator : public CalculatorBase {
|
||||
REGISTER_CALCULATOR(GlSurfaceSinkCalculator);
|
||||
|
||||
// static
|
||||
::mediapipe::Status GlSurfaceSinkCalculator::GetContract(
|
||||
CalculatorContract* cc) {
|
||||
absl::Status GlSurfaceSinkCalculator::GetContract(CalculatorContract* cc) {
|
||||
TagOrIndex(&(cc->Inputs()), "VIDEO", 0).Set<GpuBuffer>();
|
||||
cc->InputSidePackets()
|
||||
.Tag("SURFACE")
|
||||
@@ -68,7 +67,7 @@ REGISTER_CALCULATOR(GlSurfaceSinkCalculator);
|
||||
return GlCalculatorHelper::UpdateContract(cc);
|
||||
}
|
||||
|
||||
::mediapipe::Status GlSurfaceSinkCalculator::Open(CalculatorContext* cc) {
|
||||
absl::Status GlSurfaceSinkCalculator::Open(CalculatorContext* cc) {
|
||||
surface_holder_ = cc->InputSidePackets()
|
||||
.Tag("SURFACE")
|
||||
.Get<std::unique_ptr<EglSurfaceHolder>>()
|
||||
@@ -82,13 +81,13 @@ REGISTER_CALCULATOR(GlSurfaceSinkCalculator);
|
||||
return helper_.Open(cc);
|
||||
}
|
||||
|
||||
::mediapipe::Status GlSurfaceSinkCalculator::Process(CalculatorContext* cc) {
|
||||
return helper_.RunInGlContext([this, &cc]() -> ::mediapipe::Status {
|
||||
absl::Status GlSurfaceSinkCalculator::Process(CalculatorContext* cc) {
|
||||
return helper_.RunInGlContext([this, &cc]() -> absl::Status {
|
||||
absl::MutexLock lock(&surface_holder_->mutex);
|
||||
EGLSurface surface = surface_holder_->surface;
|
||||
if (surface == EGL_NO_SURFACE) {
|
||||
LOG_EVERY_N(INFO, 300) << "GlSurfaceSinkCalculator: no surface";
|
||||
return ::mediapipe::OkStatus();
|
||||
return absl::OkStatus();
|
||||
}
|
||||
|
||||
const auto& input = TagOrIndex(cc->Inputs(), "VIDEO", 0).Get<GpuBuffer>();
|
||||
@@ -139,7 +138,7 @@ REGISTER_CALCULATOR(GlSurfaceSinkCalculator);
|
||||
RET_CHECK(success) << "failed to restore old surface";
|
||||
|
||||
src.Release();
|
||||
return ::mediapipe::OkStatus();
|
||||
return absl::OkStatus();
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@@ -63,7 +63,8 @@ bool GlTextureBuffer::CreateInternal(const void* data) {
|
||||
if (!name_) return false;
|
||||
|
||||
glBindTexture(target_, name_);
|
||||
GlTextureInfo info = GlTextureInfoForGpuBufferFormat(format_, 0);
|
||||
GlTextureInfo info =
|
||||
GlTextureInfoForGpuBufferFormat(format_, 0, context->GetGlVersion());
|
||||
|
||||
// See b/70294573 for details about this.
|
||||
if (info.gl_internal_format == GL_RGBA16F &&
|
||||
|
||||
@@ -37,6 +37,7 @@ static void AdaptGlTextureInfoForGLES2(GlTextureInfo* info) {
|
||||
info->gl_internal_format = info->gl_format = GL_LUMINANCE;
|
||||
return;
|
||||
case GL_RG16F:
|
||||
case GL_RG32F:
|
||||
// Should this be GL_RG_EXT instead?
|
||||
info->gl_internal_format = info->gl_format = GL_LUMINANCE_ALPHA;
|
||||
return;
|
||||
@@ -52,16 +53,6 @@ static void AdaptGlTextureInfoForGLES2(GlTextureInfo* info) {
|
||||
}
|
||||
#endif // GL_ES_VERSION_2_0
|
||||
|
||||
const GlTextureInfo& GlTextureInfoForGpuBufferFormat(GpuBufferFormat format,
|
||||
int plane) {
|
||||
#if defined(__APPLE__) && TARGET_OS_OSX
|
||||
constexpr GlVersion default_version = GlVersion::kGL;
|
||||
#else
|
||||
constexpr GlVersion default_version = GlVersion::kGLES3;
|
||||
#endif // defined(__APPLE__) && TARGET_OS_OSX
|
||||
return GlTextureInfoForGpuBufferFormat(format, plane, default_version);
|
||||
}
|
||||
|
||||
const GlTextureInfo& GlTextureInfoForGpuBufferFormat(GpuBufferFormat format,
|
||||
int plane,
|
||||
GlVersion gl_version) {
|
||||
|
||||
@@ -63,8 +63,6 @@ struct GlTextureInfo {
|
||||
int downscale;
|
||||
};
|
||||
|
||||
const GlTextureInfo& GlTextureInfoForGpuBufferFormat(GpuBufferFormat format,
|
||||
int plane);
|
||||
const GlTextureInfo& GlTextureInfoForGpuBufferFormat(GpuBufferFormat format,
|
||||
int plane,
|
||||
GlVersion gl_version);
|
||||
|
||||
@@ -82,7 +82,7 @@ class GpuBufferMultiPool {
|
||||
std::size_t operator()(const BufferSpec& spec) const {
|
||||
// Width and height are expected to be smaller than half the width of
|
||||
// size_t. We can combine them into a single integer, and then use
|
||||
// std::hash, which is what go/hashing recommends for hashing numbers.
|
||||
// std::hash.
|
||||
constexpr int kWidth = std::numeric_limits<size_t>::digits;
|
||||
return std::hash<std::size_t>{}(
|
||||
spec.width ^ RotateLeft(spec.height, kWidth / 2) ^
|
||||
|
||||
@@ -31,10 +31,10 @@ class GpuBufferToImageFrameCalculator : public CalculatorBase {
|
||||
public:
|
||||
GpuBufferToImageFrameCalculator() {}
|
||||
|
||||
static ::mediapipe::Status GetContract(CalculatorContract* cc);
|
||||
static absl::Status GetContract(CalculatorContract* cc);
|
||||
|
||||
::mediapipe::Status Open(CalculatorContext* cc) override;
|
||||
::mediapipe::Status Process(CalculatorContext* cc) override;
|
||||
absl::Status Open(CalculatorContext* cc) override;
|
||||
absl::Status Process(CalculatorContext* cc) override;
|
||||
|
||||
private:
|
||||
#if !MEDIAPIPE_GPU_BUFFER_USE_CV_PIXEL_BUFFER
|
||||
@@ -44,7 +44,7 @@ class GpuBufferToImageFrameCalculator : public CalculatorBase {
|
||||
REGISTER_CALCULATOR(GpuBufferToImageFrameCalculator);
|
||||
|
||||
// static
|
||||
::mediapipe::Status GpuBufferToImageFrameCalculator::GetContract(
|
||||
absl::Status GpuBufferToImageFrameCalculator::GetContract(
|
||||
CalculatorContract* cc) {
|
||||
cc->Inputs().Index(0).SetAny();
|
||||
cc->Outputs().Index(0).Set<ImageFrame>();
|
||||
@@ -52,25 +52,23 @@ REGISTER_CALCULATOR(GpuBufferToImageFrameCalculator);
|
||||
// to ensure the calculator's contract is the same. In particular, the helper
|
||||
// enables support for the legacy side packet, which several graphs still use.
|
||||
MP_RETURN_IF_ERROR(GlCalculatorHelper::UpdateContract(cc));
|
||||
return ::mediapipe::OkStatus();
|
||||
return absl::OkStatus();
|
||||
}
|
||||
|
||||
::mediapipe::Status GpuBufferToImageFrameCalculator::Open(
|
||||
CalculatorContext* cc) {
|
||||
absl::Status GpuBufferToImageFrameCalculator::Open(CalculatorContext* cc) {
|
||||
// Inform the framework that we always output at the same timestamp
|
||||
// as we receive a packet at.
|
||||
cc->SetOffset(TimestampDiff(0));
|
||||
#if !MEDIAPIPE_GPU_BUFFER_USE_CV_PIXEL_BUFFER
|
||||
MP_RETURN_IF_ERROR(helper_.Open(cc));
|
||||
#endif // MEDIAPIPE_GPU_BUFFER_USE_CV_PIXEL_BUFFER
|
||||
return ::mediapipe::OkStatus();
|
||||
return absl::OkStatus();
|
||||
}
|
||||
|
||||
::mediapipe::Status GpuBufferToImageFrameCalculator::Process(
|
||||
CalculatorContext* cc) {
|
||||
absl::Status GpuBufferToImageFrameCalculator::Process(CalculatorContext* cc) {
|
||||
if (cc->Inputs().Index(0).Value().ValidateAsType<ImageFrame>().ok()) {
|
||||
cc->Outputs().Index(0).AddPacket(cc->Inputs().Index(0).Value());
|
||||
return ::mediapipe::OkStatus();
|
||||
return absl::OkStatus();
|
||||
}
|
||||
|
||||
#ifdef HAVE_GPU_BUFFER
|
||||
@@ -87,7 +85,8 @@ REGISTER_CALCULATOR(GpuBufferToImageFrameCalculator);
|
||||
ImageFormatForGpuBufferFormat(input.format()), src.width(),
|
||||
src.height(), ImageFrame::kGlDefaultAlignmentBoundary);
|
||||
helper_.BindFramebuffer(src);
|
||||
const auto info = GlTextureInfoForGpuBufferFormat(input.format(), 0);
|
||||
const auto info = GlTextureInfoForGpuBufferFormat(input.format(), 0,
|
||||
helper_.GetGlVersion());
|
||||
glReadPixels(0, 0, src.width(), src.height(), info.gl_format,
|
||||
info.gl_type, frame->MutablePixelData());
|
||||
glFlush();
|
||||
@@ -95,12 +94,12 @@ REGISTER_CALCULATOR(GpuBufferToImageFrameCalculator);
|
||||
src.Release();
|
||||
});
|
||||
#endif // MEDIAPIPE_GPU_BUFFER_USE_CV_PIXEL_BUFFER
|
||||
return ::mediapipe::OkStatus();
|
||||
return absl::OkStatus();
|
||||
}
|
||||
#endif // defined(HAVE_GPU_BUFFER)
|
||||
|
||||
return ::mediapipe::Status(::mediapipe::StatusCode::kInvalidArgument,
|
||||
"Input packets must be ImageFrame or GpuBuffer.");
|
||||
return absl::Status(absl::StatusCode::kInvalidArgument,
|
||||
"Input packets must be ImageFrame or GpuBuffer.");
|
||||
}
|
||||
|
||||
} // namespace mediapipe
|
||||
|
||||
@@ -104,7 +104,7 @@ GpuResources::~GpuResources() {
|
||||
#endif
|
||||
}
|
||||
|
||||
mediapipe::Status GpuResources::PrepareGpuNode(CalculatorNode* node) {
|
||||
absl::Status GpuResources::PrepareGpuNode(CalculatorNode* node) {
|
||||
CHECK(node->UsesGpu());
|
||||
std::string node_id = node->GetCalculatorState().NodeName();
|
||||
std::string node_type = node->GetCalculatorState().CalculatorType();
|
||||
|
||||
@@ -42,8 +42,7 @@ namespace mediapipe {
|
||||
// TODO: rename to GpuService or GpuManager or something.
|
||||
class GpuResources {
|
||||
public:
|
||||
using StatusOrGpuResources =
|
||||
::mediapipe::StatusOr<std::shared_ptr<GpuResources>>;
|
||||
using StatusOrGpuResources = absl::StatusOr<std::shared_ptr<GpuResources>>;
|
||||
|
||||
static StatusOrGpuResources Create();
|
||||
static StatusOrGpuResources Create(PlatformGlContext external_context);
|
||||
@@ -69,7 +68,7 @@ class GpuResources {
|
||||
MPPGraphGPUData* ios_gpu_data();
|
||||
#endif // defined(__APPLE__)§
|
||||
|
||||
mediapipe::Status PrepareGpuNode(CalculatorNode* node);
|
||||
absl::Status PrepareGpuNode(CalculatorNode* node);
|
||||
|
||||
// If the node requires custom GPU executors in the current configuration,
|
||||
// returns the executor's names and the executors themselves.
|
||||
@@ -124,7 +123,7 @@ struct GpuSharedData {
|
||||
auto status_or_resources = GpuResources::Create(external_context);
|
||||
MEDIAPIPE_CHECK_OK(status_or_resources.status())
|
||||
<< ": could not create GpuResources";
|
||||
return std::move(status_or_resources).ValueOrDie();
|
||||
return std::move(status_or_resources).value();
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -28,10 +28,10 @@ class ImageFrameToGpuBufferCalculator : public CalculatorBase {
|
||||
public:
|
||||
ImageFrameToGpuBufferCalculator() {}
|
||||
|
||||
static ::mediapipe::Status GetContract(CalculatorContract* cc);
|
||||
static absl::Status GetContract(CalculatorContract* cc);
|
||||
|
||||
::mediapipe::Status Open(CalculatorContext* cc) override;
|
||||
::mediapipe::Status Process(CalculatorContext* cc) override;
|
||||
absl::Status Open(CalculatorContext* cc) override;
|
||||
absl::Status Process(CalculatorContext* cc) override;
|
||||
|
||||
private:
|
||||
#if !MEDIAPIPE_GPU_BUFFER_USE_CV_PIXEL_BUFFER
|
||||
@@ -41,7 +41,7 @@ class ImageFrameToGpuBufferCalculator : public CalculatorBase {
|
||||
REGISTER_CALCULATOR(ImageFrameToGpuBufferCalculator);
|
||||
|
||||
// static
|
||||
::mediapipe::Status ImageFrameToGpuBufferCalculator::GetContract(
|
||||
absl::Status ImageFrameToGpuBufferCalculator::GetContract(
|
||||
CalculatorContract* cc) {
|
||||
cc->Inputs().Index(0).Set<ImageFrame>();
|
||||
cc->Outputs().Index(0).Set<GpuBuffer>();
|
||||
@@ -49,22 +49,20 @@ REGISTER_CALCULATOR(ImageFrameToGpuBufferCalculator);
|
||||
// to ensure the calculator's contract is the same. In particular, the helper
|
||||
// enables support for the legacy side packet, which several graphs still use.
|
||||
MP_RETURN_IF_ERROR(GlCalculatorHelper::UpdateContract(cc));
|
||||
return ::mediapipe::OkStatus();
|
||||
return absl::OkStatus();
|
||||
}
|
||||
|
||||
::mediapipe::Status ImageFrameToGpuBufferCalculator::Open(
|
||||
CalculatorContext* cc) {
|
||||
absl::Status ImageFrameToGpuBufferCalculator::Open(CalculatorContext* cc) {
|
||||
// Inform the framework that we always output at the same timestamp
|
||||
// as we receive a packet at.
|
||||
cc->SetOffset(TimestampDiff(0));
|
||||
#if !MEDIAPIPE_GPU_BUFFER_USE_CV_PIXEL_BUFFER
|
||||
MP_RETURN_IF_ERROR(helper_.Open(cc));
|
||||
#endif // !MEDIAPIPE_GPU_BUFFER_USE_CV_PIXEL_BUFFER
|
||||
return ::mediapipe::OkStatus();
|
||||
return absl::OkStatus();
|
||||
}
|
||||
|
||||
::mediapipe::Status ImageFrameToGpuBufferCalculator::Process(
|
||||
CalculatorContext* cc) {
|
||||
absl::Status ImageFrameToGpuBufferCalculator::Process(CalculatorContext* cc) {
|
||||
#if MEDIAPIPE_GPU_BUFFER_USE_CV_PIXEL_BUFFER
|
||||
CFHolder<CVPixelBufferRef> buffer;
|
||||
MP_RETURN_IF_ERROR(CreateCVPixelBufferForImageFramePacket(
|
||||
@@ -80,7 +78,7 @@ REGISTER_CALCULATOR(ImageFrameToGpuBufferCalculator);
|
||||
src.Release();
|
||||
});
|
||||
#endif // MEDIAPIPE_GPU_BUFFER_USE_CV_PIXEL_BUFFER
|
||||
return ::mediapipe::OkStatus();
|
||||
return absl::OkStatus();
|
||||
}
|
||||
|
||||
} // namespace mediapipe
|
||||
|
||||
Reference in New Issue
Block a user