Project import generated by Copybara.

GitOrigin-RevId: 6e5aa035cd1f6a9333962df5d3ab97a05bd5744e
This commit is contained in:
MediaPipe Team
2022-06-28 12:11:05 +00:00
committed by Sebastian Schmidt
parent 4a20e9909d
commit c688862570
144 changed files with 5772 additions and 2118 deletions
+7
View File
@@ -53,6 +53,12 @@ cc_library(
deps = ["//mediapipe/framework:graph_service"],
)
cc_library(
name = "attachments",
hdrs = ["attachments.h"],
visibility = ["//visibility:public"],
)
GL_BASE_LINK_OPTS = select({
"//conditions:default": [],
"//mediapipe:android": [
@@ -172,6 +178,7 @@ cc_library(
}),
visibility = ["//visibility:public"],
deps = [
":attachments",
":gl_base",
":gl_thread_collector",
":gpu_buffer_format",
+3 -3
View File
@@ -12,8 +12,8 @@
// See the License for the specific language governing permissions and
// limitations under the License.
#ifndef MEDIAPIPE_GPU_DRISHTIGRAPHGPUDATA_H_
#define MEDIAPIPE_GPU_DRISHTIGRAPHGPUDATA_H_
#ifndef MEDIAPIPE_GPU_MPPGRAPHGPUDATA_H_
#define MEDIAPIPE_GPU_MPPGRAPHGPUDATA_H_
#import <CoreVideo/CVMetalTextureCache.h>
#import <CoreVideo/CoreVideo.h>
@@ -68,4 +68,4 @@ class GpuBufferMultiPool;
@end
#endif // MEDIAPIPE_GPU_DRISHTIGRAPHGPUDATA_H_
#endif // MEDIAPIPE_GPU_MPPGRAPHGPUDATA_H_
+64
View File
@@ -0,0 +1,64 @@
#ifndef MEDIAPIPE_GPU_ATTACHMENTS_H_
#define MEDIAPIPE_GPU_ATTACHMENTS_H_
#include <functional>
#include <memory>
namespace mediapipe {
namespace internal {
// Unique pointer with a type-erased destructor.
template <class T>
using AttachmentPtr = std::unique_ptr<T, std::function<void(void*)>>;
// Like make_unique.
template <class T, class... Args>
static std::enable_if_t<!std::is_array<T>::value, AttachmentPtr<T>>
MakeAttachmentPtr(Args&&... args) {
return {new T(std::forward<Args>(args)...),
[](void* ptr) { delete static_cast<T*>(ptr); }};
}
template <class Context>
class AttachmentBase {};
// An cacheable resource that can be associated with a context.
// Attachments are defined as constants.
// When access to an attachment is requested, it will be retrieved from the
// context if already created, or the factory function will be invoked to create
// it. The factory function for a given attachment is invoked at most once per
// context. The lifetime of the object it returns is managed by the context.
template <class Context, class T>
class Attachment : public AttachmentBase<Context> {
public:
using FactoryT = std::function<AttachmentPtr<T>(Context&)>;
Attachment(FactoryT factory) : factory_(factory) {}
Attachment(const Attachment&) = delete;
Attachment(Attachment&&) = delete;
Attachment& operator=(const Attachment&) = delete;
Attachment& operator=(Attachment&&) = delete;
T& Get(Context& ctx) const { return ctx.GetCachedAttachment(*this); }
const FactoryT& factory() const { return factory_; }
// Ptr and MakePtr here make it more convenient to define new types of
// attachment contexts, since you only need a using declaration for Attachment
// and can refer to Ptr from it.
using Ptr = AttachmentPtr<T>;
template <class... Args>
inline static std::enable_if_t<!std::is_array<T>::value, AttachmentPtr<T>>
MakePtr(Args&&... args) {
return MakeAttachmentPtr<T>(std::forward<Args>(args)...);
}
private:
FactoryT factory_;
};
} // namespace internal
} // namespace mediapipe
#endif // MEDIAPIPE_GPU_ATTACHMENTS_H_
+6 -31
View File
@@ -29,6 +29,7 @@
#include "mediapipe/framework/port/statusor.h"
#include "mediapipe/framework/port/threadpool.h"
#include "mediapipe/framework/timestamp.h"
#include "mediapipe/gpu/attachments.h"
#include "mediapipe/gpu/gl_base.h"
#include "mediapipe/gpu/gpu_buffer_format.h"
@@ -286,42 +287,15 @@ class GlContext : public std::enable_shared_from_this<GlContext> {
// Sets default texture filtering parameters.
void SetStandardTextureParams(GLenum target, GLint internal_format);
using AttachmentBase = internal::AttachmentBase<GlContext>;
template <class T>
using AttachmentPtr = std::unique_ptr<T, std::function<void(void*)>>;
template <class T, class... Args>
static std::enable_if_t<!std::is_array<T>::value, AttachmentPtr<T>>
MakeAttachmentPtr(Args&&... args) {
return {new T(std::forward<Args>(args)...),
[](void* ptr) { delete static_cast<T*>(ptr); }};
}
class AttachmentBase {};
template <class T>
class Attachment : public AttachmentBase {
public:
using FactoryT = std::function<AttachmentPtr<T>(GlContext&)>;
Attachment(FactoryT factory) : factory_(factory) {}
Attachment(const Attachment&) = delete;
Attachment(Attachment&&) = delete;
Attachment& operator=(const Attachment&) = delete;
Attachment& operator=(Attachment&&) = delete;
T& Get(GlContext& ctx) const { return ctx.GetCachedAttachment(*this); }
const FactoryT& factory() const { return factory_; }
private:
FactoryT factory_;
};
using Attachment = internal::Attachment<GlContext, T>;
// TOOD: const result?
template <class T>
T& GetCachedAttachment(const Attachment<T>& attachment) {
DCHECK(IsCurrent());
AttachmentPtr<void>& entry = attachments_[&attachment];
internal::AttachmentPtr<void>& entry = attachments_[&attachment];
if (entry == nullptr) {
entry = attachment.factory()(*this);
}
@@ -454,7 +428,8 @@ class GlContext : public std::enable_shared_from_this<GlContext> {
// better mechanism?
bool can_linear_filter_float_textures_;
absl::flat_hash_map<const AttachmentBase*, AttachmentPtr<void>> attachments_;
absl::flat_hash_map<const AttachmentBase*, internal::AttachmentPtr<void>>
attachments_;
// Number of glFinish calls completed on the GL thread.
// Changes should be guarded by mutex_. However, we use simple atomic
+1 -1
View File
@@ -11,7 +11,7 @@
namespace mediapipe {
internal::GpuBufferStorage& GpuBuffer::GetStorageForView(
TypeRef view_provider_type, bool for_writing) const {
TypeId view_provider_type, bool for_writing) const {
const std::shared_ptr<internal::GpuBufferStorage>* chosen_storage = nullptr;
// First see if any current storage supports the view.
+2 -5
View File
@@ -130,8 +130,6 @@ class GpuBuffer {
}
private:
using TypeRef = internal::TypeRef;
class PlaceholderGpuBufferStorage
: public internal::GpuBufferStorageImpl<PlaceholderGpuBufferStorage> {
public:
@@ -147,14 +145,13 @@ class GpuBuffer {
GpuBufferFormat format_ = GpuBufferFormat::kUnknown;
};
internal::GpuBufferStorage& GetStorageForView(TypeRef view_provider_type,
internal::GpuBufferStorage& GetStorageForView(TypeId view_provider_type,
bool for_writing) const;
template <class View>
internal::ViewProvider<View>* GetViewProvider(bool for_writing) const {
using VP = internal::ViewProvider<View>;
return GetStorageForView(TypeRef::Get<VP>(), for_writing)
.template down_cast<VP>();
return GetStorageForView(kTypeId<VP>, for_writing).template down_cast<VP>();
}
std::shared_ptr<internal::GpuBufferStorage>& no_storage() const {
+5 -5
View File
@@ -8,14 +8,14 @@ using StorageConverter = GpuBufferStorageRegistry::StorageConverter;
using RegistryToken = GpuBufferStorageRegistry::RegistryToken;
StorageFactory GpuBufferStorageRegistry::StorageFactoryForViewProvider(
TypeRef view_provider_type) {
TypeId view_provider_type) {
auto it = factory_for_view_provider_.find(view_provider_type);
if (it == factory_for_view_provider_.end()) return nullptr;
return it->second;
}
StorageConverter GpuBufferStorageRegistry::StorageConverterForViewProvider(
TypeRef view_provider_type, TypeRef existing_storage_type) {
TypeId view_provider_type, TypeId existing_storage_type) {
auto it = converter_for_view_provider_and_existing_storage_.find(
{view_provider_type, existing_storage_type});
if (it == converter_for_view_provider_and_existing_storage_.end())
@@ -24,7 +24,7 @@ StorageConverter GpuBufferStorageRegistry::StorageConverterForViewProvider(
}
RegistryToken GpuBufferStorageRegistry::Register(
StorageFactory factory, std::vector<TypeRef> provider_hashes) {
StorageFactory factory, std::vector<TypeId> provider_hashes) {
// TODO: choose between multiple factories for same provider type.
for (const auto p : provider_hashes) {
factory_for_view_provider_[p] = factory;
@@ -33,8 +33,8 @@ RegistryToken GpuBufferStorageRegistry::Register(
}
RegistryToken GpuBufferStorageRegistry::Register(
StorageConverter converter, std::vector<TypeRef> provider_hashes,
TypeRef source_storage) {
StorageConverter converter, std::vector<TypeId> provider_hashes,
TypeId source_storage) {
// TODO: choose between multiple converters for same provider type.
for (const auto p : provider_hashes) {
converter_for_view_provider_and_existing_storage_[{p, source_storage}] =
+22 -45
View File
@@ -1,9 +1,11 @@
#ifndef MEDIAPIPE_GPU_GPU_BUFFER_STORAGE_H_
#define MEDIAPIPE_GPU_GPU_BUFFER_STORAGE_H_
#include <cstdint>
#include <functional>
#include <memory>
#include <sstream>
#include <type_traits>
#include "absl/container/flat_hash_map.h"
#include "mediapipe/framework/deps/no_destructor.h"
@@ -20,31 +22,6 @@ struct types {};
template <class V>
class ViewProvider;
// An identifier for a type. We have often used size_t holding a hash for this
// purpose in MediaPipe, but a non-primitive type makes the code more readable.
// Ideally we should clean up the various ways this is handled throughout the
// framework and consolidate the utilities in type_util. When that is done, this
// type can be replaced.
class TypeRef {
public:
template <class T>
static TypeRef Get() {
return TypeRef{tool::GetTypeHash<T>()};
}
bool operator==(const TypeRef& other) const { return hash_ == other.hash_; }
template <typename H>
friend H AbslHashValue(H h, const TypeRef& r) {
return H::combine(std::move(h), r.hash_);
}
private:
explicit TypeRef(size_t hash) : hash_(hash) {}
size_t hash_;
};
// Interface for a backing storage for GpuBuffer.
class GpuBufferStorage {
public:
@@ -56,18 +33,18 @@ class GpuBufferStorage {
// The public methods delegate to the type-erased private virtual method.
template <class T>
T* down_cast() {
return static_cast<T*>(const_cast<void*>(down_cast(TypeRef::Get<T>())));
return static_cast<T*>(const_cast<void*>(down_cast(kTypeId<T>)));
}
template <class T>
const T* down_cast() const {
return static_cast<const T*>(down_cast(TypeRef::Get<T>()));
return static_cast<const T*>(down_cast(kTypeId<T>));
}
bool can_down_cast_to(TypeRef to) const { return down_cast(to) != nullptr; }
virtual TypeRef storage_type() const = 0;
bool can_down_cast_to(TypeId to) const { return down_cast(to) != nullptr; }
virtual TypeId storage_type() const = 0;
private:
virtual const void* down_cast(TypeRef to) const = 0;
virtual const void* down_cast(TypeId to) const = 0;
};
// Used to disambiguate between overloads by manually specifying their priority.
@@ -113,18 +90,18 @@ class GpuBufferStorageRegistry {
-> std::shared_ptr<GpuBufferStorage> {
return converter(std::static_pointer_cast<StorageFrom>(source));
},
StorageTo::GetProviderTypes(), TypeRef::Get<StorageFrom>());
StorageTo::GetProviderTypes(), kTypeId<StorageFrom>);
}
// Returns a factory function for a storage that implements
// view_provider_type.
StorageFactory StorageFactoryForViewProvider(TypeRef view_provider_type);
StorageFactory StorageFactoryForViewProvider(TypeId view_provider_type);
// Returns a conversion function that, given a storage of
// existing_storage_type, converts its contents to a new storage that
// implements view_provider_type.
StorageConverter StorageConverterForViewProvider(
TypeRef view_provider_type, TypeRef existing_storage_type);
TypeId view_provider_type, TypeId existing_storage_type);
private:
template <class Storage, class... Args>
@@ -139,13 +116,13 @@ class GpuBufferStorageRegistry {
}
RegistryToken Register(StorageFactory factory,
std::vector<TypeRef> provider_hashes);
std::vector<TypeId> provider_hashes);
RegistryToken Register(StorageConverter converter,
std::vector<TypeRef> provider_hashes,
TypeRef source_storage);
std::vector<TypeId> provider_hashes,
TypeId source_storage);
absl::flat_hash_map<TypeRef, StorageFactory> factory_for_view_provider_;
absl::flat_hash_map<std::pair<TypeRef, TypeRef>, StorageConverter>
absl::flat_hash_map<TypeId, StorageFactory> factory_for_view_provider_;
absl::flat_hash_map<std::pair<TypeId, TypeId>, StorageConverter>
converter_for_view_provider_and_existing_storage_;
};
@@ -166,21 +143,21 @@ struct ForceStaticInstantiation {
template <class T, class... U>
class GpuBufferStorageImpl : public GpuBufferStorage, public U... {
public:
static const std::vector<TypeRef>& GetProviderTypes() {
static std::vector<TypeRef> kHashes{TypeRef::Get<U>()...};
static const std::vector<TypeId>& GetProviderTypes() {
static std::vector<TypeId> kHashes{kTypeId<U>...};
return kHashes;
}
private:
virtual const void* down_cast(TypeRef to) const override {
virtual const void* down_cast(TypeId to) const override {
return down_cast_impl(to, types<T, U...>{});
}
TypeRef storage_type() const override { return TypeRef::Get<T>(); }
TypeId storage_type() const override { return kTypeId<T>; }
const void* down_cast_impl(TypeRef to, types<>) const { return nullptr; }
const void* down_cast_impl(TypeId to, types<>) const { return nullptr; }
template <class V, class... W>
const void* down_cast_impl(TypeRef to, types<V, W...>) const {
if (to == TypeRef::Get<V>()) return static_cast<const V*>(this);
const void* down_cast_impl(TypeId to, types<V, W...>) const {
if (to == kTypeId<V>) return static_cast<const V*>(this);
return down_cast_impl(to, types<W...>{});
}