Commit 4f46c7df authored by Frank Liberato's avatar Frank Liberato Committed by Commit Bot

Wait for the sync token in D3D11VideoDecoder.

When a VideoFrame is destroyed, this CL causes D3D11VideoDecoder to
wait for the sync token to clear before re-using the associated
PictureBuffer.  This ensures that any use of the underlying texture
is also done.

Bug: 832732
Cq-Include-Trybots: luci.chromium.try:android_optional_gpu_tests_rel;luci.chromium.try:linux_optional_gpu_tests_rel;luci.chromium.try:mac_optional_gpu_tests_rel;luci.chromium.try:win_optional_gpu_tests_rel
Change-Id: Icdac2bfd95e8b98ff47a1633426bb50205f05820
Reviewed-on: https://chromium-review.googlesource.com/1012507
Commit-Queue: Frank Liberato <liberato@chromium.org>
Reviewed-by: default avatarDan Sanders <sandersd@chromium.org>
Cr-Commit-Position: refs/heads/master@{#551860}
parent 8395856b
...@@ -53,6 +53,13 @@ class GLES2DecoderHelperImpl : public GLES2DecoderHelper { ...@@ -53,6 +53,13 @@ class GLES2DecoderHelperImpl : public GLES2DecoderHelper {
glGenTextures(1, &texture_id); glGenTextures(1, &texture_id);
glBindTexture(target, texture_id); glBindTexture(target, texture_id);
// Mark external textures as clear, since nobody is going to take any action
// that would "clear" them.
// TODO(liberato): should we make the client do this when it binds an image?
gfx::Rect cleared_rect = (target == GL_TEXTURE_EXTERNAL_OES)
? gfx::Rect(width, height)
: gfx::Rect();
scoped_refptr<gpu::gles2::TextureRef> texture_ref = scoped_refptr<gpu::gles2::TextureRef> texture_ref =
gpu::gles2::TextureRef::Create(texture_manager_, 0, texture_id); gpu::gles2::TextureRef::Create(texture_manager_, 0, texture_id);
texture_manager_->SetTarget(texture_ref.get(), target); texture_manager_->SetTarget(texture_ref.get(), target);
...@@ -66,7 +73,7 @@ class GLES2DecoderHelperImpl : public GLES2DecoderHelper { ...@@ -66,7 +73,7 @@ class GLES2DecoderHelperImpl : public GLES2DecoderHelper {
0, // border 0, // border
format, // format format, // format
type, // type type, // type
gfx::Rect()); // cleared_rect cleared_rect); // cleared_rect
texture_manager_->SetParameteri(__func__, decoder_->GetErrorState(), texture_manager_->SetParameteri(__func__, decoder_->GetErrorState(),
texture_ref.get(), GL_TEXTURE_MAG_FILTER, texture_ref.get(), GL_TEXTURE_MAG_FILTER,
......
...@@ -8,7 +8,9 @@ ...@@ -8,7 +8,9 @@
#include "base/threading/sequenced_task_runner_handle.h" #include "base/threading/sequenced_task_runner_handle.h"
#include "gpu/command_buffer/service/mailbox_manager.h" #include "gpu/command_buffer/service/mailbox_manager.h"
#include "gpu/command_buffer/service/scheduler.h"
#include "gpu/command_buffer/service/texture_manager.h" #include "gpu/command_buffer/service/texture_manager.h"
#include "gpu/ipc/service/gpu_channel.h"
#include "media/base/bind_to_current_loop.h" #include "media/base/bind_to_current_loop.h"
#include "media/base/cdm_context.h" #include "media/base/cdm_context.h"
#include "media/base/decoder_buffer.h" #include "media/base/decoder_buffer.h"
...@@ -35,6 +37,9 @@ D3D11VideoDecoderImpl::D3D11VideoDecoderImpl( ...@@ -35,6 +37,9 @@ D3D11VideoDecoderImpl::D3D11VideoDecoderImpl(
D3D11VideoDecoderImpl::~D3D11VideoDecoderImpl() { D3D11VideoDecoderImpl::~D3D11VideoDecoderImpl() {
// TODO(liberato): be sure to clear |picture_buffers_| on the main thread. // TODO(liberato): be sure to clear |picture_buffers_| on the main thread.
// For now, we always run on the main thread anyway. // For now, we always run on the main thread anyway.
if (stub_ && !wait_sequence_id_.is_null())
stub_->channel()->scheduler()->DestroySequence(wait_sequence_id_);
} }
std::string D3D11VideoDecoderImpl::GetDisplayName() const { std::string D3D11VideoDecoderImpl::GetDisplayName() const {
...@@ -59,6 +64,8 @@ void D3D11VideoDecoderImpl::Initialize( ...@@ -59,6 +64,8 @@ void D3D11VideoDecoderImpl::Initialize(
} }
// TODO(liberato): see GpuVideoFrameFactory. // TODO(liberato): see GpuVideoFrameFactory.
// stub_->AddDestructionObserver(this); // stub_->AddDestructionObserver(this);
wait_sequence_id_ = stub_->channel()->scheduler()->CreateSequence(
gpu::SchedulingPriority::kNormal);
// Use the ANGLE device, rather than create our own. It would be nice if we // Use the ANGLE device, rather than create our own. It would be nice if we
// could use our own device, and run on the mojo thread, but texture sharing // could use our own device, and run on the mojo thread, but texture sharing
...@@ -362,8 +369,16 @@ void D3D11VideoDecoderImpl::OnMailboxReleased( ...@@ -362,8 +369,16 @@ void D3D11VideoDecoderImpl::OnMailboxReleased(
// Note that |buffer| might no longer be in |picture_buffers_| if we've // Note that |buffer| might no longer be in |picture_buffers_| if we've
// replaced them. That's okay. // replaced them. That's okay.
// TODO(liberato): Wait for the sync token here. stub_->channel()->scheduler()->ScheduleTask(gpu::Scheduler::Task(
wait_sequence_id_,
base::BindOnce(&D3D11VideoDecoderImpl::OnSyncTokenReleased, GetWeakPtr(),
std::move(buffer)),
std::vector<gpu::SyncToken>({sync_token})));
}
void D3D11VideoDecoderImpl::OnSyncTokenReleased(
scoped_refptr<D3D11PictureBuffer> buffer) {
// Note that |buffer| might no longer be in |picture_buffers_|.
buffer->set_in_client_use(false); buffer->set_in_client_use(false);
// Also re-start decoding in case it was waiting for more pictures. // Also re-start decoding in case it was waiting for more pictures.
...@@ -371,7 +386,7 @@ void D3D11VideoDecoderImpl::OnMailboxReleased( ...@@ -371,7 +386,7 @@ void D3D11VideoDecoderImpl::OnMailboxReleased(
// probably check. // probably check.
base::ThreadTaskRunnerHandle::Get()->PostTask( base::ThreadTaskRunnerHandle::Get()->PostTask(
FROM_HERE, FROM_HERE,
base::Bind(&D3D11VideoDecoderImpl::DoDecode, weak_factory_.GetWeakPtr())); base::BindOnce(&D3D11VideoDecoderImpl::DoDecode, GetWeakPtr()));
} }
base::WeakPtr<D3D11VideoDecoderImpl> D3D11VideoDecoderImpl::GetWeakPtr() { base::WeakPtr<D3D11VideoDecoderImpl> D3D11VideoDecoderImpl::GetWeakPtr() {
......
...@@ -15,6 +15,7 @@ ...@@ -15,6 +15,7 @@
#include "base/memory/ref_counted.h" #include "base/memory/ref_counted.h"
#include "base/memory/weak_ptr.h" #include "base/memory/weak_ptr.h"
#include "gpu/command_buffer/service/sequence_id.h"
#include "gpu/ipc/service/command_buffer_stub.h" #include "gpu/ipc/service/command_buffer_stub.h"
#include "media/base/callback_registry.h" #include "media/base/callback_registry.h"
#include "media/base/video_decoder.h" #include "media/base/video_decoder.h"
...@@ -72,6 +73,7 @@ class MEDIA_GPU_EXPORT D3D11VideoDecoderImpl : public VideoDecoder, ...@@ -72,6 +73,7 @@ class MEDIA_GPU_EXPORT D3D11VideoDecoderImpl : public VideoDecoder,
void OnMailboxReleased(scoped_refptr<D3D11PictureBuffer> buffer, void OnMailboxReleased(scoped_refptr<D3D11PictureBuffer> buffer,
const gpu::SyncToken& sync_token); const gpu::SyncToken& sync_token);
void OnSyncTokenReleased(scoped_refptr<D3D11PictureBuffer> buffer);
// Callback to notify that new usable key is available. // Callback to notify that new usable key is available.
void NotifyNewKey(); void NotifyNewKey();
...@@ -111,6 +113,9 @@ class MEDIA_GPU_EXPORT D3D11VideoDecoderImpl : public VideoDecoder, ...@@ -111,6 +113,9 @@ class MEDIA_GPU_EXPORT D3D11VideoDecoderImpl : public VideoDecoder,
// Callback registration to keep the new key callback registered. // Callback registration to keep the new key callback registered.
std::unique_ptr<CallbackRegistration> new_key_callback_registration_; std::unique_ptr<CallbackRegistration> new_key_callback_registration_;
// Wait sequence for sync points.
gpu::SequenceId wait_sequence_id_;
base::WeakPtrFactory<D3D11VideoDecoderImpl> weak_factory_; base::WeakPtrFactory<D3D11VideoDecoderImpl> weak_factory_;
DISALLOW_COPY_AND_ASSIGN(D3D11VideoDecoderImpl); DISALLOW_COPY_AND_ASSIGN(D3D11VideoDecoderImpl);
......
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