Use shared_from_this in GlTextureBuffer::GetReadView, GetWriteView
This ensures that the callbacks in GlTextureView won't call an expired object, even if user code holds a GlTextureView after releasing the buffer. Note that GlTextureBuffer is not always held by a shared_ptr, but it always is when GpuBuffer calls GetRead/WriteView on it. An alternative solution would have been to have GpuBuffer pass its shared_ptr<GlTextureBuffer> to the view method, which could have been implemented with some compile-time logic to detect whether the method expects such an argument. However, that doesn't seem necessary. PiperOrigin-RevId: 489611843
This commit is contained in:
committed by
Copybara-Service
parent
bbd5da7971
commit
eb8ef1ace0
@@ -14,6 +14,8 @@
|
||||
|
||||
#include "mediapipe/gpu/gpu_buffer.h"
|
||||
|
||||
#include <utility>
|
||||
|
||||
#include "mediapipe/framework/formats/image_format.pb.h"
|
||||
#include "mediapipe/framework/port/gmock.h"
|
||||
#include "mediapipe/framework/port/gtest.h"
|
||||
@@ -206,5 +208,25 @@ TEST_F(GpuBufferTest, Overwrite) {
|
||||
}
|
||||
}
|
||||
|
||||
TEST_F(GpuBufferTest, GlTextureViewRetainsWhatItNeeds) {
|
||||
GpuBuffer buffer(300, 200, GpuBufferFormat::kBGRA32);
|
||||
{
|
||||
std::shared_ptr<ImageFrame> view = buffer.GetWriteView<ImageFrame>();
|
||||
EXPECT_EQ(view->Width(), 300);
|
||||
EXPECT_EQ(view->Height(), 200);
|
||||
FillImageFrameRGBA(*view, 255, 0, 0, 255);
|
||||
}
|
||||
|
||||
RunInGlContext([buffer = std::move(buffer)]() mutable {
|
||||
// This is not a recommended pattern, but let's make sure that we don't
|
||||
// crash if the buffer is released before the view. The view can hold
|
||||
// callbacks into its underlying storage.
|
||||
auto view = buffer.GetReadView<GlTextureView>(0);
|
||||
buffer = nullptr;
|
||||
});
|
||||
// We're really checking that we haven't crashed.
|
||||
EXPECT_TRUE(true);
|
||||
}
|
||||
|
||||
} // anonymous namespace
|
||||
} // namespace mediapipe
|
||||
|
||||
Reference in New Issue
Block a user