GpuMemoryBufferPool.cpp 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293
  1. #include "pch.h"
  2. #include <rtc_base/ref_counted_object.h>
  3. #include <system_wrappers/include/clock.h>
  4. #include "GpuMemoryBufferPool.h"
  5. namespace unity
  6. {
  7. namespace webrtc
  8. {
  9. GpuMemoryBufferPool::GpuMemoryBufferPool(IGraphicsDevice* device, Clock* clock)
  10. : device_(device)
  11. , clock_(clock)
  12. {
  13. }
  14. GpuMemoryBufferPool::~GpuMemoryBufferPool() { }
  15. rtc::scoped_refptr<VideoFrame> GpuMemoryBufferPool::CreateFrame(
  16. NativeTexPtr ptr, const Size& size, UnityRenderingExtTextureFormat format, Timestamp timestamp)
  17. {
  18. auto buffer = GetOrCreateFrameResources(ptr, size, format);
  19. VideoFrame::ReturnBufferToPoolCallback callback =
  20. std::bind(&GpuMemoryBufferPool::OnReturnBuffer, this, std::placeholders::_1);
  21. return VideoFrame::WrapExternalGpuMemoryBuffer(
  22. size, buffer, callback, webrtc::TimeDelta::Micros(timestamp.us()));
  23. }
  24. rtc::scoped_refptr<GpuMemoryBufferInterface> GpuMemoryBufferPool::GetOrCreateFrameResources(
  25. NativeTexPtr ptr, const Size& size, UnityRenderingExtTextureFormat format)
  26. {
  27. auto it = resourcesPool_.begin();
  28. while (it != resourcesPool_.end())
  29. {
  30. FrameResources* resources = it->get();
  31. if (!resources->IsUsed() && AreFrameResourcesCompatible(resources, size, format))
  32. {
  33. resources->MarkUsed(clock_->CurrentTime());
  34. GpuMemoryBufferFromUnity* buffer = static_cast<GpuMemoryBufferFromUnity*>(resources->buffer_.get());
  35. buffer->ResetSync();
  36. buffer->CopyBuffer(ptr);
  37. return resources->buffer_;
  38. }
  39. it++;
  40. }
  41. rtc::scoped_refptr<GpuMemoryBufferFromUnity> buffer =
  42. new rtc::RefCountedObject<GpuMemoryBufferFromUnity>(device_, ptr, size, format);
  43. std::unique_ptr<FrameResources> resources = std::make_unique<FrameResources>(buffer);
  44. resources->MarkUsed(clock_->CurrentTime());
  45. resourcesPool_.push_back(std::move(resources));
  46. return std::move(buffer);
  47. }
  48. bool GpuMemoryBufferPool::AreFrameResourcesCompatible(
  49. const FrameResources* resources, const Size& size, UnityRenderingExtTextureFormat format)
  50. {
  51. return resources->buffer_->GetSize() == size && resources->buffer_->GetFormat() == format;
  52. }
  53. void GpuMemoryBufferPool::OnReturnBuffer(rtc::scoped_refptr<GpuMemoryBufferInterface> buffer)
  54. {
  55. GpuMemoryBufferInterface* ptr = buffer.get();
  56. auto result = std::find_if(
  57. resourcesPool_.begin(),
  58. resourcesPool_.end(),
  59. [ptr](std::unique_ptr<FrameResources>& x) { return x->buffer_.get() == ptr; });
  60. RTC_DCHECK(result != resourcesPool_.end());
  61. (*result)->MarkUnused(clock_->CurrentTime());
  62. }
  63. void GpuMemoryBufferPool::ReleaseStaleBuffers(Timestamp now)
  64. {
  65. auto it = resourcesPool_.begin();
  66. while (it != resourcesPool_.end())
  67. {
  68. FrameResources* resources = (*it).get();
  69. constexpr TimeDelta kStaleFrameLimit = TimeDelta::Seconds(10);
  70. if (!resources->IsUsed() && now - resources->lastUseTime() > kStaleFrameLimit)
  71. {
  72. resourcesPool_.erase(it++);
  73. }
  74. else
  75. {
  76. it++;
  77. }
  78. }
  79. }
  80. }
  81. }