Make it possible to override the SimplePool factory used by MultiPool

This means MultiPool no longer needs a SetFlushPlatformCaches method, which was too specific to the CVPixelBufferPool.

PiperOrigin-RevId: 488783003
This commit is contained in:
Camillo Lugaresi 2022-11-15 16:03:03 -08:00 committed by Copybara-Service
parent 267476657d
commit b9fa2e3496
6 changed files with 31 additions and 29 deletions

View File

@ -368,6 +368,7 @@ cc_library(
], ],
}), }),
deps = [ deps = [
":cv_texture_cache_manager",
":gpu_buffer_format", ":gpu_buffer_format",
":multi_pool", ":multi_pool",
":pixel_buffer_pool_util", ":pixel_buffer_pool_util",

View File

@ -25,13 +25,13 @@ namespace mediapipe {
CvPixelBufferPoolWrapper::CvPixelBufferPoolWrapper( CvPixelBufferPoolWrapper::CvPixelBufferPoolWrapper(
int width, int height, GpuBufferFormat format, CFTimeInterval maxAge, int width, int height, GpuBufferFormat format, CFTimeInterval maxAge,
std::function<void(void)> flush_texture_caches) { CvTextureCacheManager* texture_caches) {
OSType cv_format = CVPixelFormatForGpuBufferFormat(format); OSType cv_format = CVPixelFormatForGpuBufferFormat(format);
CHECK_NE(cv_format, -1) << "unsupported pixel format"; CHECK_NE(cv_format, -1) << "unsupported pixel format";
pool_ = MakeCFHolderAdopting( pool_ = MakeCFHolderAdopting(
/* keep count is 0 because the age param keeps buffers around anyway */ /* keep count is 0 because the age param keeps buffers around anyway */
CreateCVPixelBufferPool(width, height, cv_format, 0, maxAge)); CreateCVPixelBufferPool(width, height, cv_format, 0, maxAge));
flush_texture_caches_ = std::move(flush_texture_caches); texture_caches_ = texture_caches;
} }
CFHolder<CVPixelBufferRef> CvPixelBufferPoolWrapper::GetBuffer() { CFHolder<CVPixelBufferRef> CvPixelBufferPoolWrapper::GetBuffer() {
@ -47,12 +47,12 @@ CFHolder<CVPixelBufferRef> CvPixelBufferPoolWrapper::GetBuffer() {
kCFAllocatorDefault, *pool_, (__bridge CFDictionaryRef)auxAttributes, kCFAllocatorDefault, *pool_, (__bridge CFDictionaryRef)auxAttributes,
&buffer); &buffer);
if (err != kCVReturnWouldExceedAllocationThreshold) break; if (err != kCVReturnWouldExceedAllocationThreshold) break;
if (flush_texture_caches_ && !tried_flushing) { if (texture_caches_ && !tried_flushing) {
// Call the flush function to potentially release old holds on buffers // Call the flush function to potentially release old holds on buffers
// and try again to create a pixel buffer. // and try again to create a pixel buffer.
// This is used to flush CV texture caches, which may retain buffers until // This is used to flush CV texture caches, which may retain buffers until
// flushed. // flushed.
flush_texture_caches_(); texture_caches_->FlushTextureCaches();
tried_flushing = true; tried_flushing = true;
} else { } else {
++threshold; ++threshold;

View File

@ -23,6 +23,7 @@
#define MEDIAPIPE_GPU_CV_PIXEL_BUFFER_POOL_WRAPPER_H_ #define MEDIAPIPE_GPU_CV_PIXEL_BUFFER_POOL_WRAPPER_H_
#include "CoreFoundation/CFBase.h" #include "CoreFoundation/CFBase.h"
#include "mediapipe/gpu/cv_texture_cache_manager.h"
#include "mediapipe/gpu/gpu_buffer_format.h" #include "mediapipe/gpu/gpu_buffer_format.h"
#include "mediapipe/gpu/multi_pool.h" #include "mediapipe/gpu/multi_pool.h"
#include "mediapipe/gpu/pixel_buffer_pool_util.h" #include "mediapipe/gpu/pixel_buffer_pool_util.h"
@ -34,15 +35,14 @@ class CvPixelBufferPoolWrapper {
public: public:
CvPixelBufferPoolWrapper(int width, int height, GpuBufferFormat format, CvPixelBufferPoolWrapper(int width, int height, GpuBufferFormat format,
CFTimeInterval maxAge, CFTimeInterval maxAge,
std::function<void(void)> flush_texture_caches); CvTextureCacheManager* texture_caches);
static std::shared_ptr<CvPixelBufferPoolWrapper> Create( static std::shared_ptr<CvPixelBufferPoolWrapper> Create(
int width, int height, GpuBufferFormat format, int width, int height, GpuBufferFormat format,
const MultiPoolOptions& options, const MultiPoolOptions& options,
std::function<void(void)> flush_texture_caches = nullptr) { CvTextureCacheManager* texture_caches = nullptr) {
return std::make_shared<CvPixelBufferPoolWrapper>( return std::make_shared<CvPixelBufferPoolWrapper>(
width, height, format, options.max_inactive_buffer_age, width, height, format, options.max_inactive_buffer_age, texture_caches);
flush_texture_caches);
} }
CFHolder<CVPixelBufferRef> GetBuffer(); CFHolder<CVPixelBufferRef> GetBuffer();
@ -58,7 +58,7 @@ class CvPixelBufferPoolWrapper {
private: private:
CFHolder<CVPixelBufferPoolRef> pool_; CFHolder<CVPixelBufferPoolRef> pool_;
int count_ = 0; int count_ = 0;
std::function<void(void)> flush_texture_caches_; CvTextureCacheManager* texture_caches_;
}; };
} // namespace mediapipe } // namespace mediapipe

View File

@ -24,15 +24,10 @@
namespace mediapipe { namespace mediapipe {
std::shared_ptr<GpuBufferMultiPool::SimplePool> std::shared_ptr<GpuBufferMultiPool::SimplePool>
GpuBufferMultiPool::MakeSimplePool(const GpuBufferMultiPool::BufferSpec& spec, GpuBufferMultiPool::DefaultMakeSimplePool(
const GpuBufferMultiPool::BufferSpec& spec,
const MultiPoolOptions& options) { const MultiPoolOptions& options) {
#if MEDIAPIPE_GPU_BUFFER_USE_CV_PIXEL_BUFFER return SimplePool::Create(spec.width, spec.height, spec.format, options);
return CvPixelBufferPoolWrapper::Create(spec.width, spec.height, spec.format,
options, flush_platform_caches_);
#else
return GlTextureBufferPool::Create(spec.width, spec.height, spec.format,
options);
#endif // MEDIAPIPE_GPU_BUFFER_USE_CV_PIXEL_BUFFER
} }
std::shared_ptr<GpuBufferMultiPool::SimplePool> GpuBufferMultiPool::RequestPool( std::shared_ptr<GpuBufferMultiPool::SimplePool> GpuBufferMultiPool::RequestPool(
@ -44,7 +39,7 @@ std::shared_ptr<GpuBufferMultiPool::SimplePool> GpuBufferMultiPool::RequestPool(
pool = pool =
cache_.Lookup(spec, [this](const BufferSpec& spec, int request_count) { cache_.Lookup(spec, [this](const BufferSpec& spec, int request_count) {
return (request_count >= options_.min_requests_before_pool) return (request_count >= options_.min_requests_before_pool)
? MakeSimplePool(spec, options_) ? create_simple_pool_(spec, options_)
: nullptr; : nullptr;
}); });
evicted = cache_.Evict(options_.max_pool_count, evicted = cache_.Evict(options_.max_pool_count,

View File

@ -52,10 +52,6 @@ class GpuBufferMultiPool {
GpuBuffer GetBuffer(int width, int height, GpuBuffer GetBuffer(int width, int height,
GpuBufferFormat format = GpuBufferFormat::kBGRA32); GpuBufferFormat format = GpuBufferFormat::kBGRA32);
void SetFlushPlatformCaches(std::function<void(void)> flush_platform_caches) {
flush_platform_caches_ = flush_platform_caches;
}
// This class is not intended as part of the public api of this class. It is // This class is not intended as part of the public api of this class. It is
// public only because it is used as a map key type, and the map // public only because it is used as a map key type, and the map
// implementation needs access to, e.g., the equality operator. // implementation needs access to, e.g., the equality operator.
@ -74,14 +70,21 @@ class GpuBufferMultiPool {
mediapipe::GpuBufferFormat format; mediapipe::GpuBufferFormat format;
}; };
private:
#if MEDIAPIPE_GPU_BUFFER_USE_CV_PIXEL_BUFFER #if MEDIAPIPE_GPU_BUFFER_USE_CV_PIXEL_BUFFER
using SimplePool = CvPixelBufferPoolWrapper; using SimplePool = CvPixelBufferPoolWrapper;
#else #else
using SimplePool = GlTextureBufferPool; using SimplePool = GlTextureBufferPool;
#endif // MEDIAPIPE_GPU_BUFFER_USE_CV_PIXEL_BUFFER #endif // MEDIAPIPE_GPU_BUFFER_USE_CV_PIXEL_BUFFER
std::shared_ptr<SimplePool> MakeSimplePool( using SimplePoolFactory = std::function<std::shared_ptr<SimplePool>(
const BufferSpec& spec, const MultiPoolOptions& options)>;
void SetSimplePoolFactory(SimplePoolFactory create_simple_pool) {
create_simple_pool_ = create_simple_pool;
}
private:
static std::shared_ptr<SimplePool> DefaultMakeSimplePool(
const GpuBufferMultiPool::BufferSpec& spec, const GpuBufferMultiPool::BufferSpec& spec,
const MultiPoolOptions& options); const MultiPoolOptions& options);
@ -94,8 +97,7 @@ class GpuBufferMultiPool {
absl::Mutex mutex_; absl::Mutex mutex_;
mediapipe::ResourceCache<BufferSpec, std::shared_ptr<SimplePool>> cache_ mediapipe::ResourceCache<BufferSpec, std::shared_ptr<SimplePool>> cache_
ABSL_GUARDED_BY(mutex_); ABSL_GUARDED_BY(mutex_);
// This is used to hook up the TextureCacheManager on Apple platforms. SimplePoolFactory create_simple_pool_ = DefaultMakeSimplePool;
std::function<void(void)> flush_platform_caches_;
}; };
// BufferSpec equality operators // BufferSpec equality operators

View File

@ -86,8 +86,12 @@ GpuResources::GpuResources(std::shared_ptr<GlContext> gl_context) {
std::make_shared<GlContextExecutor>(gl_context.get()); std::make_shared<GlContextExecutor>(gl_context.get());
#if __APPLE__ #if __APPLE__
texture_caches_ = std::make_shared<CvTextureCacheManager>(); texture_caches_ = std::make_shared<CvTextureCacheManager>();
gpu_buffer_pool().SetFlushPlatformCaches( gpu_buffer_pool().SetSimplePoolFactory(
[tc = texture_caches_] { tc->FlushTextureCaches(); }); [tc = texture_caches_](const GpuBufferMultiPool::BufferSpec& spec,
const MultiPoolOptions& options) {
return CvPixelBufferPoolWrapper::Create(spec.width, spec.height,
spec.format, options, tc.get());
});
#if MEDIAPIPE_GPU_BUFFER_USE_CV_PIXEL_BUFFER #if MEDIAPIPE_GPU_BUFFER_USE_CV_PIXEL_BUFFER
texture_caches_->RegisterTextureCache(gl_context->cv_texture_cache()); texture_caches_->RegisterTextureCache(gl_context->cv_texture_cache());
#endif // MEDIAPIPE_GPU_BUFFER_USE_CV_PIXEL_BUFFER #endif // MEDIAPIPE_GPU_BUFFER_USE_CV_PIXEL_BUFFER