Commit b9990f83 authored by Sergey Ulanov's avatar Sergey Ulanov Committed by Commit Bot

[Fuchsia] Pass RasterContextProvider to FuchsiaVideoDecoder

Previously RasterContextProvider kept raw pointers to
SharedImageInterface and ContextSupport interfaces. These pointers were
also passed to OutputMailbox instances, which may outlive the decoder.
There as nothing to guarantee that OutputMailbox doesn't outlive the
SharedImageInterface implementation. Updated the decoder to use a
ref-counted pointer to RasterContextProvider interface. This allows to
ensure that SharedImageInterface is not destroyed before the
OutputMailbox instances that depend on it.

Bug: 1133325
Change-Id: I60b664d89207535d968cf998488457c789c800c9
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2441935Reviewed-by: default avatarWez <wez@chromium.org>
Reviewed-by: default avatarRobert Kroeger <rjkroege@chromium.org>
Reviewed-by: default avatarDan Sanders <sandersd@chromium.org>
Commit-Queue: Sergey Ulanov <sergeyu@chromium.org>
Cr-Commit-Position: refs/heads/master@{#816848}
parent 2a91bb2f
...@@ -223,6 +223,7 @@ source_set("filters") { ...@@ -223,6 +223,7 @@ source_set("filters") {
"fuchsia/fuchsia_video_decoder.h", "fuchsia/fuchsia_video_decoder.h",
] ]
deps += [ deps += [
"//components/viz/common",
"//gpu/command_buffer/client", "//gpu/command_buffer/client",
"//gpu/command_buffer/common", "//gpu/command_buffer/common",
"//gpu/ipc/common", "//gpu/ipc/common",
...@@ -334,8 +335,10 @@ source_set("unit_tests") { ...@@ -334,8 +335,10 @@ source_set("unit_tests") {
if (is_fuchsia) { if (is_fuchsia) {
sources += [ "fuchsia/fuchsia_video_decoder_unittest.cc" ] sources += [ "fuchsia/fuchsia_video_decoder_unittest.cc" ]
deps += [ deps += [
"//components/viz/common",
"//components/viz/test:test_support", "//components/viz/test:test_support",
"//gpu/command_buffer/client", "//gpu/command_buffer/client",
"//gpu/config",
"//third_party/fuchsia-sdk/sdk/fidl/fuchsia.sysmem", "//third_party/fuchsia-sdk/sdk/fidl/fuchsia.sysmem",
"//third_party/fuchsia-sdk/sdk/pkg/sys_cpp", "//third_party/fuchsia-sdk/sdk/pkg/sys_cpp",
] ]
......
include_rules = [
"+components/viz/common/gpu/raster_context_provider.h",
]
\ No newline at end of file
...@@ -24,6 +24,7 @@ ...@@ -24,6 +24,7 @@
#include "base/memory/weak_ptr.h" #include "base/memory/weak_ptr.h"
#include "base/process/process_metrics.h" #include "base/process/process_metrics.h"
#include "base/threading/sequenced_task_runner_handle.h" #include "base/threading/sequenced_task_runner_handle.h"
#include "components/viz/common/gpu/raster_context_provider.h"
#include "gpu/command_buffer/client/context_support.h" #include "gpu/command_buffer/client/context_support.h"
#include "gpu/command_buffer/client/shared_image_interface.h" #include "gpu/command_buffer/client/shared_image_interface.h"
#include "gpu/command_buffer/common/shared_image_usage.h" #include "gpu/command_buffer/common/shared_image_usage.h"
...@@ -60,22 +61,23 @@ const uint32_t kMaxUsedOutputFrames = 6; ...@@ -60,22 +61,23 @@ const uint32_t kMaxUsedOutputFrames = 6;
// outlive FuchsiaVideoDecoder if is referenced by a VideoFrame. // outlive FuchsiaVideoDecoder if is referenced by a VideoFrame.
class OutputMailbox { class OutputMailbox {
public: public:
OutputMailbox(gpu::SharedImageInterface* shared_image_interface, OutputMailbox(
gpu::ContextSupport* gpu_context_support, scoped_refptr<viz::RasterContextProvider> raster_context_provider,
std::unique_ptr<gfx::GpuMemoryBuffer> gmb) std::unique_ptr<gfx::GpuMemoryBuffer> gmb)
: shared_image_interface_(shared_image_interface), : raster_context_provider_(raster_context_provider), weak_factory_(this) {
gpu_context_support_(gpu_context_support),
weak_factory_(this) {
uint32_t usage = gpu::SHARED_IMAGE_USAGE_RASTER | uint32_t usage = gpu::SHARED_IMAGE_USAGE_RASTER |
gpu::SHARED_IMAGE_USAGE_OOP_RASTERIZATION | gpu::SHARED_IMAGE_USAGE_OOP_RASTERIZATION |
gpu::SHARED_IMAGE_USAGE_DISPLAY | gpu::SHARED_IMAGE_USAGE_DISPLAY |
gpu::SHARED_IMAGE_USAGE_SCANOUT; gpu::SHARED_IMAGE_USAGE_SCANOUT;
mailbox_ = shared_image_interface_->CreateSharedImage( mailbox_ =
gmb.get(), nullptr, gfx::ColorSpace(), kTopLeft_GrSurfaceOrigin, raster_context_provider_->SharedImageInterface()->CreateSharedImage(
kPremul_SkAlphaType, usage); gmb.get(), nullptr, gfx::ColorSpace(), kTopLeft_GrSurfaceOrigin,
kPremul_SkAlphaType, usage);
} }
~OutputMailbox() { ~OutputMailbox() {
shared_image_interface_->DestroySharedImage(sync_token_, mailbox_); raster_context_provider_->SharedImageInterface()->DestroySharedImage(
sync_token_, mailbox_);
} }
const gpu::Mailbox& mailbox() { return mailbox_; } const gpu::Mailbox& mailbox() { return mailbox_; }
...@@ -94,7 +96,8 @@ class OutputMailbox { ...@@ -94,7 +96,8 @@ class OutputMailbox {
gpu::MailboxHolder mailboxes[VideoFrame::kMaxPlanes]; gpu::MailboxHolder mailboxes[VideoFrame::kMaxPlanes];
mailboxes[0].mailbox = mailbox_; mailboxes[0].mailbox = mailbox_;
mailboxes[0].sync_token = shared_image_interface_->GenUnverifiedSyncToken(); mailboxes[0].sync_token = raster_context_provider_->SharedImageInterface()
->GenUnverifiedSyncToken();
auto frame = VideoFrame::WrapNativeTextures( auto frame = VideoFrame::WrapNativeTextures(
pixel_format, mailboxes, pixel_format, mailboxes,
...@@ -132,7 +135,7 @@ class OutputMailbox { ...@@ -132,7 +135,7 @@ class OutputMailbox {
return; return;
} }
gpu_context_support_->SignalSyncToken( raster_context_provider_->ContextSupport()->SignalSyncToken(
sync_token_, sync_token_,
BindToCurrentLoop(base::BindOnce(&OutputMailbox::OnSyncTokenSignaled, BindToCurrentLoop(base::BindOnce(&OutputMailbox::OnSyncTokenSignaled,
weak_factory_.GetWeakPtr()))); weak_factory_.GetWeakPtr())));
...@@ -143,8 +146,7 @@ class OutputMailbox { ...@@ -143,8 +146,7 @@ class OutputMailbox {
std::move(reuse_callback_).Run(); std::move(reuse_callback_).Run();
} }
gpu::SharedImageInterface* const shared_image_interface_; const scoped_refptr<viz::RasterContextProvider> raster_context_provider_;
gpu::ContextSupport* const gpu_context_support_;
gpu::Mailbox mailbox_; gpu::Mailbox mailbox_;
gpu::SyncToken sync_token_; gpu::SyncToken sync_token_;
...@@ -169,9 +171,9 @@ struct InputDecoderPacket { ...@@ -169,9 +171,9 @@ struct InputDecoderPacket {
class FuchsiaVideoDecoder : public VideoDecoder, class FuchsiaVideoDecoder : public VideoDecoder,
public FuchsiaSecureStreamDecryptor::Client { public FuchsiaSecureStreamDecryptor::Client {
public: public:
FuchsiaVideoDecoder(gpu::SharedImageInterface* shared_image_interface, FuchsiaVideoDecoder(
gpu::ContextSupport* gpu_context_support, scoped_refptr<viz::RasterContextProvider> raster_context_provider,
bool enable_sw_decoding); bool enable_sw_decoding);
~FuchsiaVideoDecoder() override; ~FuchsiaVideoDecoder() override;
// Decoder implementation. // Decoder implementation.
...@@ -248,8 +250,7 @@ class FuchsiaVideoDecoder : public VideoDecoder, ...@@ -248,8 +250,7 @@ class FuchsiaVideoDecoder : public VideoDecoder,
void ReleaseInputBuffers(); void ReleaseInputBuffers();
void ReleaseOutputBuffers(); void ReleaseOutputBuffers();
gpu::SharedImageInterface* const shared_image_interface_; const scoped_refptr<viz::RasterContextProvider> raster_context_provider_;
gpu::ContextSupport* const gpu_context_support_;
const bool enable_sw_decoding_; const bool enable_sw_decoding_;
const bool use_overlays_for_video_; const bool use_overlays_for_video_;
...@@ -311,17 +312,15 @@ class FuchsiaVideoDecoder : public VideoDecoder, ...@@ -311,17 +312,15 @@ class FuchsiaVideoDecoder : public VideoDecoder,
}; };
FuchsiaVideoDecoder::FuchsiaVideoDecoder( FuchsiaVideoDecoder::FuchsiaVideoDecoder(
gpu::SharedImageInterface* shared_image_interface, scoped_refptr<viz::RasterContextProvider> raster_context_provider,
gpu::ContextSupport* gpu_context_support,
bool enable_sw_decoding) bool enable_sw_decoding)
: shared_image_interface_(shared_image_interface), : raster_context_provider_(raster_context_provider),
gpu_context_support_(gpu_context_support),
enable_sw_decoding_(enable_sw_decoding), enable_sw_decoding_(enable_sw_decoding),
use_overlays_for_video_(base::CommandLine::ForCurrentProcess()->HasSwitch( use_overlays_for_video_(base::CommandLine::ForCurrentProcess()->HasSwitch(
switches::kUseOverlaysForVideo)), switches::kUseOverlaysForVideo)),
client_native_pixmap_factory_(ui::CreateClientNativePixmapFactoryOzone()), client_native_pixmap_factory_(ui::CreateClientNativePixmapFactoryOzone()),
weak_factory_(this) { weak_factory_(this) {
DCHECK(shared_image_interface_); DCHECK(raster_context_provider_);
weak_this_ = weak_factory_.GetWeakPtr(); weak_this_ = weak_factory_.GetWeakPtr();
} }
...@@ -889,10 +888,10 @@ void FuchsiaVideoDecoder::OnOutputPacket(fuchsia::media::Packet output_packet, ...@@ -889,10 +888,10 @@ void FuchsiaVideoDecoder::OnOutputPacket(fuchsia::media::Packet output_packet,
buffer_format, gfx::BufferUsage::GPU_READ, buffer_format, gfx::BufferUsage::GPU_READ,
gpu::GpuMemoryBufferImpl::DestructionCallback()); gpu::GpuMemoryBufferImpl::DestructionCallback());
output_mailboxes_[buffer_index] = new OutputMailbox( output_mailboxes_[buffer_index] =
shared_image_interface_, gpu_context_support_, std::move(gmb)); new OutputMailbox(raster_context_provider_, std::move(gmb));
} else { } else {
shared_image_interface_->UpdateSharedImage( raster_context_provider_->SharedImageInterface()->UpdateSharedImage(
gpu::SyncToken(), output_mailboxes_[buffer_index]->mailbox()); gpu::SyncToken(), output_mailboxes_[buffer_index]->mailbox());
} }
...@@ -1028,11 +1027,12 @@ void FuchsiaVideoDecoder::InitializeOutputBufferCollection( ...@@ -1028,11 +1027,12 @@ void FuchsiaVideoDecoder::InitializeOutputBufferCollection(
// Register the new collection with the GPU process. // Register the new collection with the GPU process.
DCHECK(!output_buffer_collection_id_); DCHECK(!output_buffer_collection_id_);
output_buffer_collection_id_ = gfx::SysmemBufferCollectionId::Create(); output_buffer_collection_id_ = gfx::SysmemBufferCollectionId::Create();
shared_image_interface_->RegisterSysmemBufferCollection( raster_context_provider_->SharedImageInterface()
output_buffer_collection_id_, ->RegisterSysmemBufferCollection(
collection_token_for_gpu.Unbind().TakeChannel(), output_buffer_collection_id_,
gfx::BufferFormat::YUV_420_BIPLANAR, gfx::BufferUsage::GPU_READ, collection_token_for_gpu.Unbind().TakeChannel(),
true /*register_with_image_pipe*/); gfx::BufferFormat::YUV_420_BIPLANAR, gfx::BufferUsage::GPU_READ,
true /*register_with_image_pipe*/);
// Pass new output buffer settings to the codec. // Pass new output buffer settings to the codec.
fuchsia::media::StreamBufferPartialSettings settings; fuchsia::media::StreamBufferPartialSettings settings;
...@@ -1081,8 +1081,8 @@ void FuchsiaVideoDecoder::ReleaseOutputBuffers() { ...@@ -1081,8 +1081,8 @@ void FuchsiaVideoDecoder::ReleaseOutputBuffers() {
// Tell the GPU process to drop the buffer collection. // Tell the GPU process to drop the buffer collection.
if (output_buffer_collection_id_) { if (output_buffer_collection_id_) {
shared_image_interface_->ReleaseSysmemBufferCollection( raster_context_provider_->SharedImageInterface()
output_buffer_collection_id_); ->ReleaseSysmemBufferCollection(output_buffer_collection_id_);
output_buffer_collection_id_ = {}; output_buffer_collection_id_ = {};
} }
} }
...@@ -1101,19 +1101,17 @@ void FuchsiaVideoDecoder::OnReuseMailbox(uint32_t buffer_index, ...@@ -1101,19 +1101,17 @@ void FuchsiaVideoDecoder::OnReuseMailbox(uint32_t buffer_index,
} }
std::unique_ptr<VideoDecoder> CreateFuchsiaVideoDecoder( std::unique_ptr<VideoDecoder> CreateFuchsiaVideoDecoder(
gpu::SharedImageInterface* shared_image_interface, scoped_refptr<viz::RasterContextProvider> raster_context_provider) {
gpu::ContextSupport* gpu_context_support) { return std::make_unique<FuchsiaVideoDecoder>(
return std::make_unique<FuchsiaVideoDecoder>(shared_image_interface, std::move(raster_context_provider),
gpu_context_support, /*enable_sw_decoding=*/false);
/*enable_sw_decoding=*/false);
} }
std::unique_ptr<VideoDecoder> CreateFuchsiaVideoDecoderForTests( std::unique_ptr<VideoDecoder> CreateFuchsiaVideoDecoderForTests(
gpu::SharedImageInterface* shared_image_interface, scoped_refptr<viz::RasterContextProvider> raster_context_provider,
gpu::ContextSupport* gpu_context_support,
bool enable_sw_decoding) { bool enable_sw_decoding) {
return std::make_unique<FuchsiaVideoDecoder>( return std::make_unique<FuchsiaVideoDecoder>(
shared_image_interface, gpu_context_support, enable_sw_decoding); std::move(raster_context_provider), enable_sw_decoding);
} }
} // namespace media } // namespace media
...@@ -7,12 +7,12 @@ ...@@ -7,12 +7,12 @@
#include <memory> #include <memory>
#include "base/memory/scoped_refptr.h"
#include "media/base/media_export.h" #include "media/base/media_export.h"
namespace gpu { namespace viz {
class ContextSupport; class RasterContextProvider;
class SharedImageInterface; } // namespace viz
} // namespace gpu
namespace media { namespace media {
...@@ -20,17 +20,14 @@ class VideoDecoder; ...@@ -20,17 +20,14 @@ class VideoDecoder;
// Creates VideoDecoder that uses fuchsia.mediacodec API. The returned // Creates VideoDecoder that uses fuchsia.mediacodec API. The returned
// VideoDecoder instance will only try to use hardware video codecs. // VideoDecoder instance will only try to use hardware video codecs.
// |shared_image_interface| and |gpu_context_support| must outlive the decoder.
MEDIA_EXPORT std::unique_ptr<VideoDecoder> CreateFuchsiaVideoDecoder( MEDIA_EXPORT std::unique_ptr<VideoDecoder> CreateFuchsiaVideoDecoder(
gpu::SharedImageInterface* shared_image_interface, scoped_refptr<viz::RasterContextProvider> raster_context_provider);
gpu::ContextSupport* gpu_context_support);
// Same as above, but also allows to enable software codecs. This is useful for // Same as above, but also allows to enable software codecs. This is useful for
// FuchsiaVideoDecoder tests that run on systems that don't have hardware // FuchsiaVideoDecoder tests that run on systems that don't have hardware
// decoder support. // decoder support.
MEDIA_EXPORT std::unique_ptr<VideoDecoder> CreateFuchsiaVideoDecoderForTests( MEDIA_EXPORT std::unique_ptr<VideoDecoder> CreateFuchsiaVideoDecoderForTests(
gpu::SharedImageInterface* shared_image_interface, scoped_refptr<viz::RasterContextProvider> raster_context_provider,
gpu::ContextSupport* gpu_context_support,
bool enable_sw_decoding); bool enable_sw_decoding);
} // namespace media } // namespace media
......
...@@ -13,9 +13,12 @@ ...@@ -13,9 +13,12 @@
#include "base/containers/flat_set.h" #include "base/containers/flat_set.h"
#include "base/fuchsia/fuchsia_logging.h" #include "base/fuchsia/fuchsia_logging.h"
#include "base/fuchsia/process_context.h" #include "base/fuchsia/process_context.h"
#include "base/test/bind_test_util.h"
#include "base/test/task_environment.h" #include "base/test/task_environment.h"
#include "components/viz/common/gpu/raster_context_provider.h"
#include "components/viz/test/test_context_support.h" #include "components/viz/test/test_context_support.h"
#include "gpu/command_buffer/client/shared_image_interface.h" #include "gpu/command_buffer/client/shared_image_interface.h"
#include "gpu/config/gpu_feature_info.h"
#include "media/base/test_data_util.h" #include "media/base/test_data_util.h"
#include "media/base/test_helpers.h" #include "media/base/test_helpers.h"
#include "media/base/video_decoder.h" #include "media/base/video_decoder.h"
...@@ -89,7 +92,7 @@ class TestSharedImageInterface : public gpu::SharedImageInterface { ...@@ -89,7 +92,7 @@ class TestSharedImageInterface : public gpu::SharedImageInterface {
SkAlphaType alpha_type, SkAlphaType alpha_type,
uint32_t usage, uint32_t usage,
gpu::SurfaceHandle surface_handle) override { gpu::SurfaceHandle surface_handle) override {
NOTREACHED(); ADD_FAILURE();
return gpu::Mailbox(); return gpu::Mailbox();
} }
...@@ -101,7 +104,7 @@ class TestSharedImageInterface : public gpu::SharedImageInterface { ...@@ -101,7 +104,7 @@ class TestSharedImageInterface : public gpu::SharedImageInterface {
SkAlphaType alpha_type, SkAlphaType alpha_type,
uint32_t usage, uint32_t usage,
base::span<const uint8_t> pixel_data) override { base::span<const uint8_t> pixel_data) override {
NOTREACHED(); ADD_FAILURE();
return gpu::Mailbox(); return gpu::Mailbox();
} }
...@@ -128,12 +131,12 @@ class TestSharedImageInterface : public gpu::SharedImageInterface { ...@@ -128,12 +131,12 @@ class TestSharedImageInterface : public gpu::SharedImageInterface {
void UpdateSharedImage(const gpu::SyncToken& sync_token, void UpdateSharedImage(const gpu::SyncToken& sync_token,
const gpu::Mailbox& mailbox) override { const gpu::Mailbox& mailbox) override {
NOTREACHED(); ADD_FAILURE();
} }
void UpdateSharedImage(const gpu::SyncToken& sync_token, void UpdateSharedImage(const gpu::SyncToken& sync_token,
std::unique_ptr<gfx::GpuFence> acquire_fence, std::unique_ptr<gfx::GpuFence> acquire_fence,
const gpu::Mailbox& mailbox) override { const gpu::Mailbox& mailbox) override {
NOTREACHED(); ADD_FAILURE();
} }
void DestroySharedImage(const gpu::SyncToken& sync_token, void DestroySharedImage(const gpu::SyncToken& sync_token,
...@@ -147,12 +150,12 @@ class TestSharedImageInterface : public gpu::SharedImageInterface { ...@@ -147,12 +150,12 @@ class TestSharedImageInterface : public gpu::SharedImageInterface {
GrSurfaceOrigin surface_origin, GrSurfaceOrigin surface_origin,
SkAlphaType alpha_type, SkAlphaType alpha_type,
uint32_t usage) override { uint32_t usage) override {
NOTREACHED(); ADD_FAILURE();
return SwapChainMailboxes(); return SwapChainMailboxes();
} }
void PresentSwapChain(const gpu::SyncToken& sync_token, void PresentSwapChain(const gpu::SyncToken& sync_token,
const gpu::Mailbox& mailbox) override { const gpu::Mailbox& mailbox) override {
NOTREACHED(); ADD_FAILURE();
} }
void RegisterSysmemBufferCollection(gfx::SysmemBufferCollectionId id, void RegisterSysmemBufferCollection(gfx::SysmemBufferCollectionId id,
...@@ -173,7 +176,7 @@ class TestSharedImageInterface : public gpu::SharedImageInterface { ...@@ -173,7 +176,7 @@ class TestSharedImageInterface : public gpu::SharedImageInterface {
} }
gpu::SyncToken GenVerifiedSyncToken() override { gpu::SyncToken GenVerifiedSyncToken() override {
NOTREACHED(); ADD_FAILURE();
return gpu::SyncToken(); return gpu::SyncToken();
} }
gpu::SyncToken GenUnverifiedSyncToken() override { gpu::SyncToken GenUnverifiedSyncToken() override {
...@@ -182,10 +185,10 @@ class TestSharedImageInterface : public gpu::SharedImageInterface { ...@@ -182,10 +185,10 @@ class TestSharedImageInterface : public gpu::SharedImageInterface {
} }
void WaitSyncToken(const gpu::SyncToken& sync_token) override { void WaitSyncToken(const gpu::SyncToken& sync_token) override {
NOTREACHED(); ADD_FAILURE();
} }
void Flush() override { NOTREACHED(); } void Flush() override { ADD_FAILURE(); }
scoped_refptr<gfx::NativePixmap> GetNativePixmap( scoped_refptr<gfx::NativePixmap> GetNativePixmap(
const gpu::Mailbox& mailbox) override { const gpu::Mailbox& mailbox) override {
...@@ -200,16 +203,93 @@ class TestSharedImageInterface : public gpu::SharedImageInterface { ...@@ -200,16 +203,93 @@ class TestSharedImageInterface : public gpu::SharedImageInterface {
base::flat_set<gpu::Mailbox> mailboxes_; base::flat_set<gpu::Mailbox> mailboxes_;
}; };
class TestRasterContextProvider
: public base::RefCountedThreadSafe<TestRasterContextProvider>,
public viz::RasterContextProvider {
public:
TestRasterContextProvider() {}
TestRasterContextProvider(TestRasterContextProvider&) = delete;
TestRasterContextProvider& operator=(TestRasterContextProvider&) = delete;
void SetOnDestroyedClosure(base::Closure on_destroyed) {
on_destroyed_ = on_destroyed;
}
// viz::RasterContextProvider implementation;
void AddRef() const override {
base::RefCountedThreadSafe<TestRasterContextProvider>::AddRef();
}
void Release() const override {
base::RefCountedThreadSafe<TestRasterContextProvider>::Release();
}
gpu::ContextResult BindToCurrentThread() override {
ADD_FAILURE();
return gpu::ContextResult::kFatalFailure;
}
void AddObserver(viz::ContextLostObserver* obs) override { ADD_FAILURE(); }
void RemoveObserver(viz::ContextLostObserver* obs) override { ADD_FAILURE(); }
base::Lock* GetLock() override {
ADD_FAILURE();
return nullptr;
}
viz::ContextCacheController* CacheController() override {
ADD_FAILURE();
return nullptr;
}
gpu::ContextSupport* ContextSupport() override {
return &gpu_context_support_;
}
class GrDirectContext* GrContext() override {
ADD_FAILURE();
return nullptr;
}
gpu::SharedImageInterface* SharedImageInterface() override {
return &shared_image_interface_;
}
const gpu::Capabilities& ContextCapabilities() const override {
ADD_FAILURE();
static gpu::Capabilities dummy_caps;
return dummy_caps;
}
const gpu::GpuFeatureInfo& GetGpuFeatureInfo() const override {
ADD_FAILURE();
static gpu::GpuFeatureInfo dummy_feature_info;
return dummy_feature_info;
}
gpu::gles2::GLES2Interface* ContextGL() override {
ADD_FAILURE();
return nullptr;
}
gpu::raster::RasterInterface* RasterInterface() override {
ADD_FAILURE();
return nullptr;
}
private:
friend class base::RefCountedThreadSafe<TestRasterContextProvider>;
~TestRasterContextProvider() override {
if (on_destroyed_)
std::move(on_destroyed_).Run();
}
TestSharedImageInterface shared_image_interface_;
viz::TestContextSupport gpu_context_support_;
base::Closure on_destroyed_;
};
} // namespace } // namespace
class FuchsiaVideoDecoderTest : public testing::Test { class FuchsiaVideoDecoderTest : public testing::Test {
public: public:
FuchsiaVideoDecoderTest() { FuchsiaVideoDecoderTest()
decoder_ = CreateFuchsiaVideoDecoderForTests(&shared_image_interface_, : raster_context_provider_(
&gpu_context_support_, base::MakeRefCounted<TestRasterContextProvider>()),
decoder_(
/*enable_sw_decoding=*/true); CreateFuchsiaVideoDecoderForTests(raster_context_provider_.get(),
} /*enable_sw_decoding=*/true)) {}
~FuchsiaVideoDecoderTest() override = default; ~FuchsiaVideoDecoderTest() override = default;
bool InitializeDecoder(VideoDecoderConfig config) WARN_UNUSED_RESULT { bool InitializeDecoder(VideoDecoderConfig config) WARN_UNUSED_RESULT {
...@@ -285,8 +365,7 @@ class FuchsiaVideoDecoderTest : public testing::Test { ...@@ -285,8 +365,7 @@ class FuchsiaVideoDecoderTest : public testing::Test {
base::test::SingleThreadTaskEnvironment task_environment_{ base::test::SingleThreadTaskEnvironment task_environment_{
base::test::SingleThreadTaskEnvironment::MainThreadType::IO}; base::test::SingleThreadTaskEnvironment::MainThreadType::IO};
TestSharedImageInterface shared_image_interface_; scoped_refptr<TestRasterContextProvider> raster_context_provider_;
viz::TestContextSupport gpu_context_support_;
std::unique_ptr<VideoDecoder> decoder_; std::unique_ptr<VideoDecoder> decoder_;
...@@ -396,4 +475,35 @@ TEST_F(FuchsiaVideoDecoderTest, ResetAndReinitializeH264) { ...@@ -396,4 +475,35 @@ TEST_F(FuchsiaVideoDecoderTest, ResetAndReinitializeH264) {
EXPECT_EQ(num_output_frames_, 4U); EXPECT_EQ(num_output_frames_, 4U);
} }
// Verifies that the decoder keeps reference to the RasterContextProvider.
TEST_F(FuchsiaVideoDecoderTest, RasterContextLifetime) {
bool context_destroyed = false;
raster_context_provider_->SetOnDestroyedClosure(base::BindLambdaForTesting(
[&context_destroyed]() { context_destroyed = true; }));
ASSERT_TRUE(InitializeDecoder(TestVideoConfig::NormalH264()));
ASSERT_FALSE(context_destroyed);
// Decoder should keep reference to RasterContextProvider.
raster_context_provider_.reset();
ASSERT_FALSE(context_destroyed);
// Feed some frames to decoder to get decoded video frames.
for (int i = 0; i < 4; ++i) {
DecodeBuffer(GetH264Frame(i));
}
ASSERT_NO_FATAL_FAILURE(WaitDecodeDone());
// Destroy the decoder. RasterContextProvider will not be destroyed since
// it's still referenced by frames in |output_frames_|.
decoder_.reset();
task_environment_.RunUntilIdle();
ASSERT_FALSE(context_destroyed);
// RasterContextProvider reference should be dropped once all frames are
// dropped.
output_frames_.clear();
task_environment_.RunUntilIdle();
ASSERT_TRUE(context_destroyed);
}
} // namespace media } // namespace media
...@@ -133,9 +133,7 @@ void DefaultDecoderFactory::CreateVideoDecoders( ...@@ -133,9 +133,7 @@ void DefaultDecoderFactory::CreateVideoDecoders(
// //
// TODO(crbug.com/580386): Handle context loss properly. // TODO(crbug.com/580386): Handle context loss properly.
if (context_provider) { if (context_provider) {
video_decoders->push_back( video_decoders->push_back(CreateFuchsiaVideoDecoder(context_provider));
CreateFuchsiaVideoDecoder(gpu_factories->SharedImageInterface(),
context_provider->ContextSupport()));
} else { } else {
DLOG(ERROR) DLOG(ERROR)
<< "Can't create FuchsiaVideoDecoder due to GPU context loss."; << "Can't create FuchsiaVideoDecoder due to GPU context loss.";
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment