Project import generated by Copybara.
GitOrigin-RevId: 6e5aa035cd1f6a9333962df5d3ab97a05bd5744e
This commit is contained in:
committed by
Sebastian Schmidt
parent
4a20e9909d
commit
c688862570
@@ -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",
|
||||
|
||||
@@ -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_
|
||||
|
||||
@@ -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_
|
||||
@@ -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
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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}] =
|
||||
|
||||
@@ -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...>{});
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user