Commit 3886bdd4 authored by liberato@chromium.org's avatar liberato@chromium.org Committed by Commit Bot

Switch D3D11VideoDecoder to use CommandBufferHelper.

In preparation for adding more tests to D3D11VideoDecoder, this CL
converts use of the command decoder stub to CommandBufferHelper.
Otherwise, we have to mock out the stub for the test.

Change-Id: I4234841d26dbb0187e626cfd20d534916506b8d4
Reviewed-on: https://chromium-review.googlesource.com/c/1343340
Commit-Queue: Frank Liberato <liberato@chromium.org>
Reviewed-by: default avatarDan Sanders <sandersd@chromium.org>
Cr-Commit-Position: refs/heads/master@{#610194}
parent 34a97ceb
...@@ -126,6 +126,19 @@ class CommandBufferHelperImpl ...@@ -126,6 +126,19 @@ class CommandBufferHelperImpl
return decoder_helper_->CreateMailbox(textures_[service_id].get()); return decoder_helper_->CreateMailbox(textures_[service_id].get());
} }
void ProduceTexture(const gpu::Mailbox& mailbox, GLuint service_id) override {
DVLOG(2) << __func__ << "(" << mailbox.ToDebugString() << ", " << service_id
<< ")";
DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
if (!decoder_helper_)
return;
DCHECK(textures_.count(service_id));
return decoder_helper_->ProduceTexture(mailbox,
textures_[service_id].get());
}
void WaitForSyncToken(gpu::SyncToken sync_token, void WaitForSyncToken(gpu::SyncToken sync_token,
base::OnceClosure done_cb) override { base::OnceClosure done_cb) override {
DVLOG(2) << __func__; DVLOG(2) << __func__;
......
...@@ -101,6 +101,11 @@ class MEDIA_GPU_EXPORT CommandBufferHelper ...@@ -101,6 +101,11 @@ class MEDIA_GPU_EXPORT CommandBufferHelper
// be to add a HasStub() method, and not define behavior when it is false. // be to add a HasStub() method, and not define behavior when it is false.
virtual gpu::Mailbox CreateMailbox(GLuint service_id) = 0; virtual gpu::Mailbox CreateMailbox(GLuint service_id) = 0;
// Produce a texture into a mailbox. The context does not have to be current.
// However, this will fail if the stub has been destroyed.
virtual void ProduceTexture(const gpu::Mailbox& mailbox,
GLuint service_id) = 0;
// Waits for a SyncToken, then runs |done_cb|. // Waits for a SyncToken, then runs |done_cb|.
// //
// |done_cb| may be destructed without running if the stub is destroyed. // |done_cb| may be destructed without running if the stub is destroyed.
......
...@@ -121,6 +121,13 @@ gpu::Mailbox FakeCommandBufferHelper::CreateMailbox(GLuint service_id) { ...@@ -121,6 +121,13 @@ gpu::Mailbox FakeCommandBufferHelper::CreateMailbox(GLuint service_id) {
return gpu::Mailbox::Generate(); return gpu::Mailbox::Generate();
} }
void FakeCommandBufferHelper::ProduceTexture(const gpu::Mailbox& mailbox,
GLuint service_id) {
DVLOG(2) << __func__ << "(" << service_id << ")";
DCHECK(task_runner_->BelongsToCurrentThread());
DCHECK(service_ids_.count(service_id));
}
void FakeCommandBufferHelper::WaitForSyncToken(gpu::SyncToken sync_token, void FakeCommandBufferHelper::WaitForSyncToken(gpu::SyncToken sync_token,
base::OnceClosure done_cb) { base::OnceClosure done_cb) {
DVLOG(2) << __func__; DVLOG(2) << __func__;
......
...@@ -53,6 +53,7 @@ class FakeCommandBufferHelper : public CommandBufferHelper { ...@@ -53,6 +53,7 @@ class FakeCommandBufferHelper : public CommandBufferHelper {
gl::GLImage* image, gl::GLImage* image,
bool client_managed) override; bool client_managed) override;
gpu::Mailbox CreateMailbox(GLuint service_id) override; gpu::Mailbox CreateMailbox(GLuint service_id) override;
void ProduceTexture(const gpu::Mailbox& mailbox, GLuint service_id) override;
void WaitForSyncToken(gpu::SyncToken sync_token, void WaitForSyncToken(gpu::SyncToken sync_token,
base::OnceClosure done_cb) override; base::OnceClosure done_cb) override;
void SetWillDestroyStubCB(WillDestroyStubCB will_destroy_stub_cb) override; void SetWillDestroyStubCB(WillDestroyStubCB will_destroy_stub_cb) override;
......
...@@ -89,6 +89,12 @@ class GLES2DecoderHelperImpl : public GLES2DecoderHelper { ...@@ -89,6 +89,12 @@ class GLES2DecoderHelperImpl : public GLES2DecoderHelper {
return mailbox; return mailbox;
} }
void ProduceTexture(const gpu::Mailbox& mailbox,
AbstractTexture* texture) override {
DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
mailbox_manager_->ProduceTexture(mailbox, texture->GetTextureBase());
}
private: private:
gpu::DecoderContext* decoder_; gpu::DecoderContext* decoder_;
gpu::gles2::TextureManager* texture_manager_; gpu::gles2::TextureManager* texture_manager_;
......
...@@ -62,6 +62,10 @@ class MEDIA_GPU_EXPORT GLES2DecoderHelper { ...@@ -62,6 +62,10 @@ class MEDIA_GPU_EXPORT GLES2DecoderHelper {
// Creates a mailbox for a texture. // Creates a mailbox for a texture.
virtual gpu::Mailbox CreateMailbox( virtual gpu::Mailbox CreateMailbox(
gpu::gles2::AbstractTexture* texture_ref) = 0; gpu::gles2::AbstractTexture* texture_ref) = 0;
// Produce a texture into a mailbox.
virtual void ProduceTexture(const gpu::Mailbox& mailbox,
gpu::gles2::AbstractTexture* texture_ref) = 0;
}; };
} // namespace media } // namespace media
......
...@@ -12,7 +12,6 @@ ...@@ -12,7 +12,6 @@
#include "gpu/command_buffer/service/mailbox_manager.h" #include "gpu/command_buffer/service/mailbox_manager.h"
#include "gpu/command_buffer/service/texture_manager.h" #include "gpu/command_buffer/service/texture_manager.h"
#include "media/gpu/gles2_decoder_helper.h"
#include "media/gpu/windows/return_on_failure.h" #include "media/gpu/windows/return_on_failure.h"
#include "third_party/angle/include/EGL/egl.h" #include "third_party/angle/include/EGL/egl.h"
#include "third_party/angle/include/EGL/eglext.h" #include "third_party/angle/include/EGL/eglext.h"
...@@ -25,14 +24,6 @@ ...@@ -25,14 +24,6 @@
namespace media { namespace media {
namespace {
static bool MakeContextCurrent(gpu::CommandBufferStub* stub) {
return stub && stub->decoder_context()->MakeCurrent();
}
} // namespace
D3D11PictureBuffer::D3D11PictureBuffer(GLenum target, D3D11PictureBuffer::D3D11PictureBuffer(GLenum target,
gfx::Size size, gfx::Size size,
size_t level) size_t level)
...@@ -43,7 +34,7 @@ D3D11PictureBuffer::~D3D11PictureBuffer() { ...@@ -43,7 +34,7 @@ D3D11PictureBuffer::~D3D11PictureBuffer() {
} }
bool D3D11PictureBuffer::Init( bool D3D11PictureBuffer::Init(
base::RepeatingCallback<gpu::CommandBufferStub*()> get_stub_cb, base::RepeatingCallback<scoped_refptr<CommandBufferHelper>()> get_helper_cb,
Microsoft::WRL::ComPtr<ID3D11VideoDevice> video_device, Microsoft::WRL::ComPtr<ID3D11VideoDevice> video_device,
Microsoft::WRL::ComPtr<ID3D11Texture2D> texture, Microsoft::WRL::ComPtr<ID3D11Texture2D> texture,
const GUID& decoder_guid, const GUID& decoder_guid,
...@@ -75,7 +66,7 @@ bool D3D11PictureBuffer::Init( ...@@ -75,7 +66,7 @@ bool D3D11PictureBuffer::Init(
// a handle that we get from |texture| as an IDXGIResource1. // a handle that we get from |texture| as an IDXGIResource1.
// TODO(liberato): this should happen on the gpu thread. // TODO(liberato): this should happen on the gpu thread.
gpu_resources_ = std::make_unique<GpuResources>(); gpu_resources_ = std::make_unique<GpuResources>();
if (!gpu_resources_->Init(std::move(get_stub_cb), level_, if (!gpu_resources_->Init(std::move(get_helper_cb), level_,
std::move(mailboxes), target_, size_, texture, std::move(mailboxes), target_, size_, texture,
textures_per_picture)) textures_per_picture))
return false; return false;
...@@ -85,39 +76,33 @@ bool D3D11PictureBuffer::Init( ...@@ -85,39 +76,33 @@ bool D3D11PictureBuffer::Init(
D3D11PictureBuffer::GpuResources::GpuResources() {} D3D11PictureBuffer::GpuResources::GpuResources() {}
D3D11PictureBuffer::GpuResources::~GpuResources() {} D3D11PictureBuffer::GpuResources::~GpuResources() {
if (helper_ && helper_->MakeContextCurrent()) {
for (uint32_t service_id : service_ids_)
helper_->DestroyTexture(service_id);
}
}
bool D3D11PictureBuffer::GpuResources::Init( bool D3D11PictureBuffer::GpuResources::Init(
base::RepeatingCallback<gpu::CommandBufferStub*()> get_stub_cb, base::RepeatingCallback<scoped_refptr<CommandBufferHelper>()> get_helper_cb,
int level, int level,
const std::vector<gpu::Mailbox> mailboxes, const std::vector<gpu::Mailbox> mailboxes,
GLenum target, GLenum target,
gfx::Size size, gfx::Size size,
Microsoft::WRL::ComPtr<ID3D11Texture2D> angle_texture, Microsoft::WRL::ComPtr<ID3D11Texture2D> angle_texture,
int textures_per_picture) { int textures_per_picture) {
gpu::CommandBufferStub* stub = get_stub_cb.Run(); helper_ = get_helper_cb.Run();
if (!MakeContextCurrent(stub))
return false;
auto decoder_helper = GLES2DecoderHelper::Create(stub->decoder_context()); if (!helper_ || !helper_->MakeContextCurrent())
gpu::gles2::ContextGroup* group = stub->decoder_context()->GetContextGroup();
gpu::MailboxManager* mailbox_manager = group->mailbox_manager();
gpu::gles2::TextureManager* texture_manager = group->texture_manager();
RETURN_ON_FAILURE(!!texture_manager, "No texture manager", false);
if (!texture_manager)
return false; return false;
// Create the textures and attach them to the mailboxes. // Create the textures and attach them to the mailboxes.
std::vector<uint32_t> service_ids;
for (int texture_idx = 0; texture_idx < textures_per_picture; texture_idx++) { for (int texture_idx = 0; texture_idx < textures_per_picture; texture_idx++) {
textures_.push_back(decoder_helper->CreateTexture( uint32_t service_id =
target, GL_RGBA, size.width(), size.height(), GL_RGBA, helper_->CreateTexture(target, GL_RGBA, size.width(), size.height(),
GL_UNSIGNED_BYTE)); GL_RGBA, GL_UNSIGNED_BYTE);
service_ids.push_back(textures_[texture_idx]->service_id()); service_ids_.push_back(service_id);
helper_->ProduceTexture(mailboxes[texture_idx], service_id);
mailbox_manager->ProduceTexture(mailboxes[texture_idx],
textures_[texture_idx]->GetTextureBase());
} }
// Create the stream for zero-copy use by gl. // Create the stream for zero-copy use by gl.
...@@ -133,14 +118,17 @@ bool D3D11PictureBuffer::GpuResources::Init( ...@@ -133,14 +118,17 @@ bool D3D11PictureBuffer::GpuResources::Init(
RETURN_ON_FAILURE(!!stream, "Could not create stream", false); RETURN_ON_FAILURE(!!stream, "Could not create stream", false);
// |stream| will be destroyed when the GLImage is. // |stream| will be destroyed when the GLImage is.
// TODO(liberato): for tests, it will be destroyed pretty much at the end of
// this function unless |helper_| retains it. Also, this won't work if we
// have a FakeCommandBufferHelper since the service IDs aren't meaningful.
scoped_refptr<gl::GLImage> gl_image = scoped_refptr<gl::GLImage> gl_image =
base::MakeRefCounted<gl::GLImageDXGI>(size, stream); base::MakeRefCounted<gl::GLImageDXGI>(size, stream);
gl::ScopedActiveTexture texture0(GL_TEXTURE0); gl::ScopedActiveTexture texture0(GL_TEXTURE0);
gl::ScopedTextureBinder texture0_binder(GL_TEXTURE_EXTERNAL_OES, gl::ScopedTextureBinder texture0_binder(GL_TEXTURE_EXTERNAL_OES,
service_ids[0]); service_ids_[0]);
gl::ScopedActiveTexture texture1(GL_TEXTURE1); gl::ScopedActiveTexture texture1(GL_TEXTURE1);
gl::ScopedTextureBinder texture1_binder(GL_TEXTURE_EXTERNAL_OES, gl::ScopedTextureBinder texture1_binder(GL_TEXTURE_EXTERNAL_OES,
service_ids[1]); service_ids_[1]);
EGLAttrib consumer_attributes[] = { EGLAttrib consumer_attributes[] = {
EGL_COLOR_BUFFER_TYPE, EGL_COLOR_BUFFER_TYPE,
...@@ -183,9 +171,10 @@ bool D3D11PictureBuffer::GpuResources::Init( ...@@ -183,9 +171,10 @@ bool D3D11PictureBuffer::GpuResources::Init(
gl_image_dxgi->SetTexture(angle_texture, level); gl_image_dxgi->SetTexture(angle_texture, level);
// Bind the image to each texture. // Bind the image to each texture.
for (size_t texture_idx = 0; texture_idx < textures_.size(); texture_idx++) { for (size_t texture_idx = 0; texture_idx < service_ids_.size();
textures_[texture_idx]->BindImage(gl_image.get(), texture_idx++) {
false /* client_managed */); helper_->BindImage(service_ids_[texture_idx], gl_image.get(),
false /* client_managed */);
} }
return true; return true;
......
...@@ -16,6 +16,7 @@ ...@@ -16,6 +16,7 @@
#include "gpu/command_buffer/service/texture_manager.h" #include "gpu/command_buffer/service/texture_manager.h"
#include "gpu/ipc/service/command_buffer_stub.h" #include "gpu/ipc/service/command_buffer_stub.h"
#include "media/base/video_frame.h" #include "media/base/video_frame.h"
#include "media/gpu/command_buffer_helper.h"
#include "media/gpu/media_gpu_export.h" #include "media/gpu/media_gpu_export.h"
#include "media/video/picture.h" #include "media/video/picture.h"
#include "third_party/angle/include/EGL/egl.h" #include "third_party/angle/include/EGL/egl.h"
...@@ -44,7 +45,8 @@ class MEDIA_GPU_EXPORT D3D11PictureBuffer ...@@ -44,7 +45,8 @@ class MEDIA_GPU_EXPORT D3D11PictureBuffer
D3D11PictureBuffer(GLenum target, gfx::Size size, size_t level); D3D11PictureBuffer(GLenum target, gfx::Size size, size_t level);
bool Init(base::RepeatingCallback<gpu::CommandBufferStub*()> get_stub_cb, bool Init(base::RepeatingCallback<scoped_refptr<CommandBufferHelper>()>
get_helper_cb,
Microsoft::WRL::ComPtr<ID3D11VideoDevice> video_device, Microsoft::WRL::ComPtr<ID3D11VideoDevice> video_device,
Microsoft::WRL::ComPtr<ID3D11Texture2D> texture, Microsoft::WRL::ComPtr<ID3D11Texture2D> texture,
const GUID& decoder_guid, const GUID& decoder_guid,
...@@ -101,7 +103,8 @@ class MEDIA_GPU_EXPORT D3D11PictureBuffer ...@@ -101,7 +103,8 @@ class MEDIA_GPU_EXPORT D3D11PictureBuffer
GpuResources(); GpuResources();
~GpuResources(); ~GpuResources();
bool Init(base::RepeatingCallback<gpu::CommandBufferStub*()> get_stub_cb, bool Init(base::RepeatingCallback<scoped_refptr<CommandBufferHelper>()>
get_helper_cb,
int level, int level,
const std::vector<gpu::Mailbox> mailboxes, const std::vector<gpu::Mailbox> mailboxes,
GLenum target, GLenum target,
...@@ -109,9 +112,11 @@ class MEDIA_GPU_EXPORT D3D11PictureBuffer ...@@ -109,9 +112,11 @@ class MEDIA_GPU_EXPORT D3D11PictureBuffer
Microsoft::WRL::ComPtr<ID3D11Texture2D> angle_texture, Microsoft::WRL::ComPtr<ID3D11Texture2D> angle_texture,
int textures_per_picture); int textures_per_picture);
std::vector<std::unique_ptr<gpu::gles2::AbstractTexture>> textures_; std::vector<uint32_t> service_ids_;
private: private:
scoped_refptr<CommandBufferHelper> helper_;
DISALLOW_COPY_AND_ASSIGN(GpuResources); DISALLOW_COPY_AND_ASSIGN(GpuResources);
}; };
......
...@@ -10,6 +10,7 @@ ...@@ -10,6 +10,7 @@
#include "base/bind.h" #include "base/bind.h"
#include "base/callback.h" #include "base/callback.h"
#include "base/feature_list.h" #include "base/feature_list.h"
#include "base/memory/ref_counted_delete_on_sequence.h"
#include "base/metrics/histogram_macros.h" #include "base/metrics/histogram_macros.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"
...@@ -47,6 +48,39 @@ bool IsUnsupportedVP9Profile(const VideoDecoderConfig& config) { ...@@ -47,6 +48,39 @@ bool IsUnsupportedVP9Profile(const VideoDecoderConfig& config) {
#undef INRANGE #undef INRANGE
// Holder class, so that we don't keep creating CommandBufferHelpers every time
// somebody calls a callback. We can't actually create it until we're on the
// right thread.
struct CommandBufferHelperHolder
: base::RefCountedDeleteOnSequence<CommandBufferHelperHolder> {
CommandBufferHelperHolder(
scoped_refptr<base::SequencedTaskRunner> task_runner)
: base::RefCountedDeleteOnSequence<CommandBufferHelperHolder>(
std::move(task_runner)) {}
scoped_refptr<CommandBufferHelper> helper;
private:
~CommandBufferHelperHolder() = default;
friend class base::RefCountedDeleteOnSequence<CommandBufferHelperHolder>;
friend class base::DeleteHelper<CommandBufferHelperHolder>;
DISALLOW_COPY_AND_ASSIGN(CommandBufferHelperHolder);
};
scoped_refptr<CommandBufferHelper> CreateCommandBufferHelper(
base::RepeatingCallback<gpu::CommandBufferStub*()> get_stub_cb,
scoped_refptr<CommandBufferHelperHolder> holder) {
gpu::CommandBufferStub* stub = get_stub_cb.Run();
if (!stub)
return nullptr;
DCHECK(holder);
if (!holder->helper)
holder->helper = CommandBufferHelper::Create(stub);
return holder->helper;
}
} // namespace } // namespace
std::unique_ptr<VideoDecoder> D3D11VideoDecoder::Create( std::unique_ptr<VideoDecoder> D3D11VideoDecoder::Create(
...@@ -62,12 +96,16 @@ std::unique_ptr<VideoDecoder> D3D11VideoDecoder::Create( ...@@ -62,12 +96,16 @@ std::unique_ptr<VideoDecoder> D3D11VideoDecoder::Create(
// Note that we WrapUnique<VideoDecoder> rather than D3D11VideoDecoder to make // Note that we WrapUnique<VideoDecoder> rather than D3D11VideoDecoder to make
// this castable; the deleters have to match. // this castable; the deleters have to match.
std::unique_ptr<MediaLog> cloned_media_log = media_log->Clone(); std::unique_ptr<MediaLog> cloned_media_log = media_log->Clone();
auto get_helper_cb =
base::BindRepeating(CreateCommandBufferHelper, std::move(get_stub_cb),
scoped_refptr<CommandBufferHelperHolder>(
new CommandBufferHelperHolder(gpu_task_runner)));
return base::WrapUnique<VideoDecoder>( return base::WrapUnique<VideoDecoder>(
new D3D11VideoDecoder(std::move(gpu_task_runner), std::move(media_log), new D3D11VideoDecoder(std::move(gpu_task_runner), std::move(media_log),
gpu_preferences, gpu_workarounds, gpu_preferences, gpu_workarounds,
std::make_unique<D3D11VideoDecoderImpl>( std::make_unique<D3D11VideoDecoderImpl>(
std::move(cloned_media_log), get_stub_cb), std::move(cloned_media_log), get_helper_cb),
get_stub_cb)); get_helper_cb));
} }
D3D11VideoDecoder::D3D11VideoDecoder( D3D11VideoDecoder::D3D11VideoDecoder(
...@@ -76,14 +114,14 @@ D3D11VideoDecoder::D3D11VideoDecoder( ...@@ -76,14 +114,14 @@ D3D11VideoDecoder::D3D11VideoDecoder(
const gpu::GpuPreferences& gpu_preferences, const gpu::GpuPreferences& gpu_preferences,
const gpu::GpuDriverBugWorkarounds& gpu_workarounds, const gpu::GpuDriverBugWorkarounds& gpu_workarounds,
std::unique_ptr<D3D11VideoDecoderImpl> impl, std::unique_ptr<D3D11VideoDecoderImpl> impl,
base::RepeatingCallback<gpu::CommandBufferStub*()> get_stub_cb) base::RepeatingCallback<scoped_refptr<CommandBufferHelper>()> get_helper_cb)
: media_log_(std::move(media_log)), : media_log_(std::move(media_log)),
impl_(std::move(impl)), impl_(std::move(impl)),
impl_task_runner_(std::move(gpu_task_runner)), impl_task_runner_(std::move(gpu_task_runner)),
gpu_preferences_(gpu_preferences), gpu_preferences_(gpu_preferences),
gpu_workarounds_(gpu_workarounds), gpu_workarounds_(gpu_workarounds),
create_device_func_(base::BindRepeating(D3D11CreateDevice)), create_device_func_(base::BindRepeating(D3D11CreateDevice)),
get_stub_cb_(get_stub_cb), get_helper_cb_(std::move(get_helper_cb)),
weak_factory_(this) { weak_factory_(this) {
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
...@@ -526,7 +564,7 @@ void D3D11VideoDecoder::CreatePictureBuffers() { ...@@ -526,7 +564,7 @@ void D3D11VideoDecoder::CreatePictureBuffers() {
for (size_t i = 0; i < num_buffers; i++) { for (size_t i = 0; i < num_buffers; i++) {
picture_buffers_.push_back( picture_buffers_.push_back(
new D3D11PictureBuffer(GL_TEXTURE_EXTERNAL_OES, size, i)); new D3D11PictureBuffer(GL_TEXTURE_EXTERNAL_OES, size, i));
if (!picture_buffers_[i]->Init(get_stub_cb_, video_device_, out_texture, if (!picture_buffers_[i]->Init(get_helper_cb_, video_device_, out_texture,
decoder_guid_, textures_per_picture)) { decoder_guid_, textures_per_picture)) {
NotifyError("Unable to allocate PictureBuffer"); NotifyError("Unable to allocate PictureBuffer");
return; return;
......
...@@ -17,6 +17,7 @@ ...@@ -17,6 +17,7 @@
#include "gpu/config/gpu_preferences.h" #include "gpu/config/gpu_preferences.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"
#include "media/gpu/command_buffer_helper.h"
#include "media/gpu/media_gpu_export.h" #include "media/gpu/media_gpu_export.h"
#include "media/gpu/windows/d3d11_create_device_cb.h" #include "media/gpu/windows/d3d11_create_device_cb.h"
#include "media/gpu/windows/d3d11_h264_accelerator.h" #include "media/gpu/windows/d3d11_h264_accelerator.h"
...@@ -40,7 +41,7 @@ class MediaLog; ...@@ -40,7 +41,7 @@ class MediaLog;
class MEDIA_GPU_EXPORT D3D11VideoDecoder : public VideoDecoder, class MEDIA_GPU_EXPORT D3D11VideoDecoder : public VideoDecoder,
public D3D11VideoDecoderClient { public D3D11VideoDecoderClient {
public: public:
// |get_stub_cb| must be called from |gpu_task_runner|. // |helper| must be called from |gpu_task_runner|.
static std::unique_ptr<VideoDecoder> Create( static std::unique_ptr<VideoDecoder> Create(
scoped_refptr<base::SingleThreadTaskRunner> gpu_task_runner, scoped_refptr<base::SingleThreadTaskRunner> gpu_task_runner,
std::unique_ptr<MediaLog> media_log, std::unique_ptr<MediaLog> media_log,
...@@ -91,7 +92,8 @@ class MEDIA_GPU_EXPORT D3D11VideoDecoder : public VideoDecoder, ...@@ -91,7 +92,8 @@ class MEDIA_GPU_EXPORT D3D11VideoDecoder : public VideoDecoder,
const gpu::GpuPreferences& gpu_preferences, const gpu::GpuPreferences& gpu_preferences,
const gpu::GpuDriverBugWorkarounds& gpu_workarounds, const gpu::GpuDriverBugWorkarounds& gpu_workarounds,
std::unique_ptr<D3D11VideoDecoderImpl> impl, std::unique_ptr<D3D11VideoDecoderImpl> impl,
base::RepeatingCallback<gpu::CommandBufferStub*()> get_stub_cb); base::RepeatingCallback<scoped_refptr<CommandBufferHelper>()>
get_helper_cb);
// Receive |buffer|, that is now unused by the client. // Receive |buffer|, that is now unused by the client.
void ReceivePictureBufferFromClient(scoped_refptr<D3D11PictureBuffer> buffer); void ReceivePictureBufferFromClient(scoped_refptr<D3D11PictureBuffer> buffer);
...@@ -224,6 +226,10 @@ class MEDIA_GPU_EXPORT D3D11VideoDecoder : public VideoDecoder, ...@@ -224,6 +226,10 @@ class MEDIA_GPU_EXPORT D3D11VideoDecoder : public VideoDecoder,
State state_ = State::kInitializing; State state_ = State::kInitializing;
// Callback to get a command buffer helper. Must be called from the gpu main
// thread only.
base::RepeatingCallback<scoped_refptr<CommandBufferHelper>()> get_helper_cb_;
// Entire class should be single-sequence. // Entire class should be single-sequence.
SEQUENCE_CHECKER(sequence_checker_); SEQUENCE_CHECKER(sequence_checker_);
......
...@@ -12,28 +12,17 @@ ...@@ -12,28 +12,17 @@
namespace media { namespace media {
namespace {
static bool MakeContextCurrent(gpu::CommandBufferStub* stub) {
return stub && stub->decoder_context()->MakeCurrent();
}
} // namespace
D3D11VideoDecoderImpl::D3D11VideoDecoderImpl( D3D11VideoDecoderImpl::D3D11VideoDecoderImpl(
std::unique_ptr<MediaLog> media_log, std::unique_ptr<MediaLog> media_log,
base::RepeatingCallback<gpu::CommandBufferStub*()> get_stub_cb) base::RepeatingCallback<scoped_refptr<CommandBufferHelper>()> get_helper_cb)
: media_log_(std::move(media_log)), : media_log_(std::move(media_log)),
get_stub_cb_(get_stub_cb), get_helper_cb_(std::move(get_helper_cb)),
weak_factory_(this) { weak_factory_(this) {
// May be called from any thread. // May be called from any thread.
} }
D3D11VideoDecoderImpl::~D3D11VideoDecoderImpl() { D3D11VideoDecoderImpl::~D3D11VideoDecoderImpl() {
DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
if (stub_)
DestroyStub();
} }
void D3D11VideoDecoderImpl::Initialize( void D3D11VideoDecoderImpl::Initialize(
...@@ -43,30 +32,25 @@ void D3D11VideoDecoderImpl::Initialize( ...@@ -43,30 +32,25 @@ void D3D11VideoDecoderImpl::Initialize(
return_picture_buffer_cb_ = std::move(return_picture_buffer_cb); return_picture_buffer_cb_ = std::move(return_picture_buffer_cb);
// If already have a stub, then we're as initialized as we need to be. // If have a helper, then we're as initialized as we need to be.
if (stub_) { if (helper_) {
std::move(init_cb).Run(true); std::move(init_cb).Run(true);
return; return;
} }
helper_ = get_helper_cb_.Run();
// First init. Get the stub, register, and generally do stuff. // Get the stub, register, and generally do stuff.
stub_ = get_stub_cb_.Run(); if (!helper_ || !helper_->MakeContextCurrent()) {
if (!MakeContextCurrent(stub_)) { const char* reason = "Failed to make context current.";
const char* reason = "Failed to get decoder stub";
DLOG(ERROR) << reason; DLOG(ERROR) << reason;
if (media_log_) { if (media_log_) {
media_log_->AddEvent(media_log_->CreateStringEvent( media_log_->AddEvent(media_log_->CreateStringEvent(
MediaLogEvent::MEDIA_ERROR_LOG_ENTRY, "error", reason)); MediaLogEvent::MEDIA_ERROR_LOG_ENTRY, "error", reason));
} }
stub_ = nullptr;
std::move(init_cb).Run(false); std::move(init_cb).Run(false);
return; return;
} }
stub_->AddDestructionObserver(this);
wait_sequence_id_ = stub_->channel()->scheduler()->CreateSequence(
gpu::SchedulingPriority::kNormal);
std::move(init_cb).Run(true); std::move(init_cb).Run(true);
} }
...@@ -75,14 +59,12 @@ void D3D11VideoDecoderImpl::OnMailboxReleased( ...@@ -75,14 +59,12 @@ void D3D11VideoDecoderImpl::OnMailboxReleased(
const gpu::SyncToken& sync_token) { const gpu::SyncToken& sync_token) {
DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
if (!stub_) if (!helper_)
return; return;
stub_->channel()->scheduler()->ScheduleTask(gpu::Scheduler::Task( helper_->WaitForSyncToken(
wait_sequence_id_, sync_token, base::BindOnce(&D3D11VideoDecoderImpl::OnSyncTokenReleased,
base::BindOnce(&D3D11VideoDecoderImpl::OnSyncTokenReleased, GetWeakPtr(), GetWeakPtr(), std::move(buffer)));
std::move(buffer)),
std::vector<gpu::SyncToken>({sync_token})));
} }
void D3D11VideoDecoderImpl::OnSyncTokenReleased( void D3D11VideoDecoderImpl::OnSyncTokenReleased(
...@@ -92,21 +74,6 @@ void D3D11VideoDecoderImpl::OnSyncTokenReleased( ...@@ -92,21 +74,6 @@ void D3D11VideoDecoderImpl::OnSyncTokenReleased(
return_picture_buffer_cb_.Run(std::move(buffer)); return_picture_buffer_cb_.Run(std::move(buffer));
} }
void D3D11VideoDecoderImpl::OnWillDestroyStub(bool have_context) {
DestroyStub();
}
void D3D11VideoDecoderImpl::DestroyStub() {
DCHECK(stub_);
gpu::CommandBufferStub* stub = stub_;
stub_ = nullptr;
stub->RemoveDestructionObserver(this);
if (!wait_sequence_id_.is_null())
stub->channel()->scheduler()->DestroySequence(wait_sequence_id_);
}
base::WeakPtr<D3D11VideoDecoderImpl> D3D11VideoDecoderImpl::GetWeakPtr() { base::WeakPtr<D3D11VideoDecoderImpl> D3D11VideoDecoderImpl::GetWeakPtr() {
// May be called from any thread. // May be called from any thread.
return weak_factory_.GetWeakPtr(); return weak_factory_.GetWeakPtr();
......
...@@ -17,12 +17,10 @@ ...@@ -17,12 +17,10 @@
#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 "base/threading/thread_checker.h" #include "base/threading/thread_checker.h"
#include "gpu/command_buffer/service/sequence_id.h" #include "media/gpu/command_buffer_helper.h"
#include "gpu/ipc/service/command_buffer_stub.h"
#include "media/gpu/media_gpu_export.h" #include "media/gpu/media_gpu_export.h"
namespace gpu { namespace gpu {
class CommandBufferStub;
struct SyncToken; struct SyncToken;
} // namespace gpu } // namespace gpu
...@@ -34,14 +32,14 @@ class D3D11PictureBuffer; ...@@ -34,14 +32,14 @@ class D3D11PictureBuffer;
// Does the gpu main thread work for D3D11VideoDecoder. Except as noted, this // Does the gpu main thread work for D3D11VideoDecoder. Except as noted, this
// class lives on the GPU main thread. // class lives on the GPU main thread.
// TODO(liberato): Rename this class as a follow-on to this refactor. // TODO(liberato): Rename this class as a follow-on to this refactor.
class MEDIA_GPU_EXPORT D3D11VideoDecoderImpl class MEDIA_GPU_EXPORT D3D11VideoDecoderImpl {
: public gpu::CommandBufferStub::DestructionObserver {
public: public:
// May be constructed on any thread. // May be constructed on any thread.
explicit D3D11VideoDecoderImpl( explicit D3D11VideoDecoderImpl(
std::unique_ptr<MediaLog> media_log, std::unique_ptr<MediaLog> media_log,
base::RepeatingCallback<gpu::CommandBufferStub*()> get_stub_cb); base::RepeatingCallback<scoped_refptr<CommandBufferHelper>()>
~D3D11VideoDecoderImpl() override; get_helper_cb);
virtual ~D3D11VideoDecoderImpl();
using InitCB = base::OnceCallback<void(bool success)>; using InitCB = base::OnceCallback<void(bool success)>;
...@@ -66,21 +64,14 @@ class MEDIA_GPU_EXPORT D3D11VideoDecoderImpl ...@@ -66,21 +64,14 @@ class MEDIA_GPU_EXPORT D3D11VideoDecoderImpl
private: private:
void OnSyncTokenReleased(scoped_refptr<D3D11PictureBuffer> buffer); void OnSyncTokenReleased(scoped_refptr<D3D11PictureBuffer> buffer);
void OnWillDestroyStub(bool have_context) override;
void DestroyStub();
std::unique_ptr<MediaLog> media_log_; std::unique_ptr<MediaLog> media_log_;
base::RepeatingCallback<gpu::CommandBufferStub*()> get_stub_cb_;
gpu::CommandBufferStub* stub_ = nullptr;
// Wait sequence for sync points.
gpu::SequenceId wait_sequence_id_;
// Called when we get a picture buffer back from the client. // Called when we get a picture buffer back from the client.
ReturnPictureBufferCB return_picture_buffer_cb_; ReturnPictureBufferCB return_picture_buffer_cb_;
base::RepeatingCallback<scoped_refptr<CommandBufferHelper>()> get_helper_cb_;
scoped_refptr<CommandBufferHelper> helper_;
// Has thread affinity -- must be run on the gpu main thread. // Has thread affinity -- must be run on the gpu main thread.
THREAD_CHECKER(thread_checker_); THREAD_CHECKER(thread_checker_);
......
...@@ -36,7 +36,7 @@ class MockD3D11VideoDecoderImpl : public D3D11VideoDecoderImpl { ...@@ -36,7 +36,7 @@ class MockD3D11VideoDecoderImpl : public D3D11VideoDecoderImpl {
MockD3D11VideoDecoderImpl() MockD3D11VideoDecoderImpl()
: D3D11VideoDecoderImpl( : D3D11VideoDecoderImpl(
nullptr, nullptr,
base::RepeatingCallback<gpu::CommandBufferStub*()>()) {} base::RepeatingCallback<scoped_refptr<CommandBufferHelper>()>()) {}
void Initialize(InitCB init_cb, void Initialize(InitCB init_cb,
ReturnPictureBufferCB return_picture_buffer_cb) override { ReturnPictureBufferCB return_picture_buffer_cb) override {
...@@ -74,8 +74,7 @@ class D3D11VideoDecoderTest : public ::testing::Test { ...@@ -74,8 +74,7 @@ class D3D11VideoDecoderTest : public ::testing::Test {
d3d11_decoder_raw_ = new D3D11VideoDecoder( d3d11_decoder_raw_ = new D3D11VideoDecoder(
gpu_task_runner_, nullptr /* MediaLog */, gpu_preferences_, gpu_task_runner_, nullptr /* MediaLog */, gpu_preferences_,
gpu_workarounds_, std::move(impl), gpu_workarounds_, std::move(impl),
base::BindRepeating( base::RepeatingCallback<scoped_refptr<CommandBufferHelper>()>()));
[]() -> gpu::CommandBufferStub* { return nullptr; })));
d3d11_decoder_raw_->SetCreateDeviceCallbackForTesting( d3d11_decoder_raw_->SetCreateDeviceCallbackForTesting(
base::BindRepeating(&D3D11CreateDeviceMock::Create, base::BindRepeating(&D3D11CreateDeviceMock::Create,
base::Unretained(&create_device_mock_))); base::Unretained(&create_device_mock_)));
......
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