Commit 9ddc3cd8 authored by liberato@chromium.org's avatar liberato@chromium.org Committed by Commit Bot

Remove |owner_pb| from D3D11TextureWrapper.

TextureWrapper::ProcessTexture is now given the d3d texture, array
slice directly.  By decoupling the decoder and copy / bind steps,
it makes it easier to build the standalone TextureImporter to
handle the latter.

Change-Id: I9c4261172e8d2c868f34751831b1e7b184c67c57
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2003077
Commit-Queue: Frank Liberato <liberato@chromium.org>
Reviewed-by: default avatarTed Meyer <tmathmeyer@chromium.org>
Cr-Commit-Position: refs/heads/master@{#742773}
parent bd02a9b0
...@@ -11,10 +11,15 @@ namespace media { ...@@ -11,10 +11,15 @@ namespace media {
// UMA yet! // UMA yet!
enum class ErrorCode : uint32_t { enum class ErrorCode : uint32_t {
kOk = 0, kOk = 0,
kCodeOnlyForTesting = 1,
kCannotMakeContextCurrent = 1000,
kCouldNotPostTexture = 1001,
kCouldNotPostAcquireStream = 1002,
kCodeOnlyForTesting = 10000,
kMaxValue = kCodeOnlyForTesting, kMaxValue = kCodeOnlyForTesting,
}; };
} // namespace media } // namespace media
#endif // MEDIA_BASE_MEDIA_ERROR_CODES_H_ #endif // MEDIA_BASE_MEDIA_ERROR_CODES_H_
\ No newline at end of file
...@@ -13,12 +13,14 @@ namespace media { ...@@ -13,12 +13,14 @@ namespace media {
// TODO(tmathmeyer) What D3D11 Resources do we need to do the copying? // TODO(tmathmeyer) What D3D11 Resources do we need to do the copying?
CopyingTexture2DWrapper::CopyingTexture2DWrapper( CopyingTexture2DWrapper::CopyingTexture2DWrapper(
const gfx::Size& size,
std::unique_ptr<Texture2DWrapper> output_wrapper, std::unique_ptr<Texture2DWrapper> output_wrapper,
std::unique_ptr<VideoProcessorProxy> processor, std::unique_ptr<VideoProcessorProxy> processor,
ComD3D11Texture2D input_texture) ComD3D11Texture2D output_texture)
: Texture2DWrapper(input_texture), : size_(size),
video_processor_(std::move(processor)), video_processor_(std::move(processor)),
output_texture_wrapper_(std::move(output_wrapper)) {} output_texture_wrapper_(std::move(output_wrapper)),
output_texture_(std::move(output_texture)) {}
CopyingTexture2DWrapper::~CopyingTexture2DWrapper() = default; CopyingTexture2DWrapper::~CopyingTexture2DWrapper() = default;
...@@ -29,23 +31,23 @@ CopyingTexture2DWrapper::~CopyingTexture2DWrapper() = default; ...@@ -29,23 +31,23 @@ CopyingTexture2DWrapper::~CopyingTexture2DWrapper() = default;
} \ } \
} while (0) } while (0)
bool CopyingTexture2DWrapper::ProcessTexture(const D3D11PictureBuffer* owner_pb, bool CopyingTexture2DWrapper::ProcessTexture(ComD3D11Texture2D texture,
size_t array_slice,
MailboxHolderArray* mailbox_dest) { MailboxHolderArray* mailbox_dest) {
D3D11_VIDEO_PROCESSOR_OUTPUT_VIEW_DESC output_view_desc = { D3D11_VIDEO_PROCESSOR_OUTPUT_VIEW_DESC output_view_desc = {
D3D11_VPOV_DIMENSION_TEXTURE2D}; D3D11_VPOV_DIMENSION_TEXTURE2D};
output_view_desc.Texture2D.MipSlice = 0; output_view_desc.Texture2D.MipSlice = 0;
ComD3D11VideoProcessorOutputView output_view; ComD3D11VideoProcessorOutputView output_view;
RETURN_ON_FAILURE(video_processor_->CreateVideoProcessorOutputView( RETURN_ON_FAILURE(video_processor_->CreateVideoProcessorOutputView(
output_texture_wrapper_->Texture().Get(), &output_view_desc, output_texture_.Get(), &output_view_desc, &output_view));
&output_view));
D3D11_VIDEO_PROCESSOR_INPUT_VIEW_DESC input_view_desc = {0}; D3D11_VIDEO_PROCESSOR_INPUT_VIEW_DESC input_view_desc = {0};
input_view_desc.ViewDimension = D3D11_VPIV_DIMENSION_TEXTURE2D; input_view_desc.ViewDimension = D3D11_VPIV_DIMENSION_TEXTURE2D;
input_view_desc.Texture2D.ArraySlice = owner_pb->level(); input_view_desc.Texture2D.ArraySlice = array_slice;
input_view_desc.Texture2D.MipSlice = 0; input_view_desc.Texture2D.MipSlice = 0;
ComD3D11VideoProcessorInputView input_view; ComD3D11VideoProcessorInputView input_view;
RETURN_ON_FAILURE(video_processor_->CreateVideoProcessorInputView( RETURN_ON_FAILURE(video_processor_->CreateVideoProcessorInputView(
Texture().Get(), &input_view_desc, &input_view)); texture.Get(), &input_view_desc, &input_view));
D3D11_VIDEO_PROCESSOR_STREAM streams = {0}; D3D11_VIDEO_PROCESSOR_STREAM streams = {0};
streams.Enable = TRUE; streams.Enable = TRUE;
...@@ -56,19 +58,15 @@ bool CopyingTexture2DWrapper::ProcessTexture(const D3D11PictureBuffer* owner_pb, ...@@ -56,19 +58,15 @@ bool CopyingTexture2DWrapper::ProcessTexture(const D3D11PictureBuffer* owner_pb,
1, // stream_count 1, // stream_count
&streams)); &streams));
return output_texture_wrapper_->ProcessTexture(owner_pb, mailbox_dest); return output_texture_wrapper_->ProcessTexture(output_texture_, 0,
mailbox_dest);
} }
bool CopyingTexture2DWrapper::Init(GetCommandBufferHelperCB get_helper_cb, bool CopyingTexture2DWrapper::Init(GetCommandBufferHelperCB get_helper_cb) {
size_t array_slice, if (!video_processor_->Init(size_.width(), size_.height()))
gfx::Size size) {
if (!video_processor_->Init(size.width(), size.height()))
return false; return false;
return output_texture_wrapper_->Init( return output_texture_wrapper_->Init(std::move(get_helper_cb));
get_helper_cb,
0, // The output texture only has an array size of 1.
size);
} }
} // namespace media } // namespace media
...@@ -15,26 +15,28 @@ ...@@ -15,26 +15,28 @@
namespace media { namespace media {
// Uses D3D11VideoProcessor to convert between an input texture2D and an output // Uses D3D11VideoProcessor to convert between an input texture2D and an output
// texture2D. // texture2D. Each instance owns its own destination texture.
class MEDIA_GPU_EXPORT CopyingTexture2DWrapper : public Texture2DWrapper { class MEDIA_GPU_EXPORT CopyingTexture2DWrapper : public Texture2DWrapper {
public: public:
// |output_wrapper| must wrap a Texture2D which is a single-entry Texture, // |output_wrapper| must wrap a Texture2D which is a single-entry Texture,
// while |input_texture| may have multiple entries. // while |input_texture| may have multiple entries.
CopyingTexture2DWrapper(std::unique_ptr<Texture2DWrapper> output_wrapper, CopyingTexture2DWrapper(const gfx::Size& size,
std::unique_ptr<Texture2DWrapper> output_wrapper,
std::unique_ptr<VideoProcessorProxy> processor, std::unique_ptr<VideoProcessorProxy> processor,
ComD3D11Texture2D input_texture); ComD3D11Texture2D output_texture);
~CopyingTexture2DWrapper() override; ~CopyingTexture2DWrapper() override;
bool ProcessTexture(const D3D11PictureBuffer* owner_pb, bool ProcessTexture(ComD3D11Texture2D texture,
size_t array_slice,
MailboxHolderArray* mailbox_dest) override; MailboxHolderArray* mailbox_dest) override;
bool Init(GetCommandBufferHelperCB get_helper_cb, bool Init(GetCommandBufferHelperCB get_helper_cb) override;
size_t array_slice,
gfx::Size size) override;
private: private:
gfx::Size size_;
std::unique_ptr<VideoProcessorProxy> video_processor_; std::unique_ptr<VideoProcessorProxy> video_processor_;
std::unique_ptr<Texture2DWrapper> output_texture_wrapper_; std::unique_ptr<Texture2DWrapper> output_texture_wrapper_;
ComD3D11Texture2D output_texture_;
}; };
} // namespace media } // namespace media
......
...@@ -56,16 +56,15 @@ class MockVideoProcessorProxy : public VideoProcessorProxy { ...@@ -56,16 +56,15 @@ class MockVideoProcessorProxy : public VideoProcessorProxy {
class MockTexture2DWrapper : public Texture2DWrapper { class MockTexture2DWrapper : public Texture2DWrapper {
public: public:
MockTexture2DWrapper() : Texture2DWrapper(nullptr) {} MockTexture2DWrapper() {}
bool ProcessTexture(const D3D11PictureBuffer* owner_pb, bool ProcessTexture(ComD3D11Texture2D texture,
size_t array_slice,
MailboxHolderArray* mailbox_dest) override { MailboxHolderArray* mailbox_dest) override {
return MockProcessTexture(); return MockProcessTexture();
} }
bool Init(GetCommandBufferHelperCB get_helper_cb, bool Init(GetCommandBufferHelperCB get_helper_cb) override {
size_t array_slice,
gfx::Size size) override {
return MockInit(); return MockInit();
} }
...@@ -149,13 +148,13 @@ INSTANTIATE_TEST_CASE_P(CopyingTexture2DWrapperTest, ...@@ -149,13 +148,13 @@ INSTANTIATE_TEST_CASE_P(CopyingTexture2DWrapperTest,
// make sure that any failures result in a total failure. // make sure that any failures result in a total failure.
TEST_P(D3D11CopyingTexture2DWrapperTest, TEST_P(D3D11CopyingTexture2DWrapperTest,
CopyingTextureWrapperProcessesCorrectly) { CopyingTextureWrapperProcessesCorrectly) {
gfx::Size size;
auto wrapper = std::make_unique<CopyingTexture2DWrapper>( auto wrapper = std::make_unique<CopyingTexture2DWrapper>(
ExpectTextureWrapper(), ExpectProcessorProxy(), nullptr); size, ExpectTextureWrapper(), ExpectProcessorProxy(), nullptr);
auto picture_buffer =
base::MakeRefCounted<D3D11PictureBuffer>(nullptr, gfx::Size(0, 0), 0);
EXPECT_EQ(wrapper->Init(CreateMockHelperCB(), 0, {}), InitSucceeds()); MailboxHolderArray mailboxes;
EXPECT_EQ(wrapper->ProcessTexture(picture_buffer.get(), nullptr), EXPECT_EQ(wrapper->Init(CreateMockHelperCB()), InitSucceeds());
EXPECT_EQ(wrapper->ProcessTexture(nullptr, 0, &mailboxes),
ProcessTextureSucceeds()); ProcessTextureSucceeds());
} }
......
...@@ -22,15 +22,16 @@ ...@@ -22,15 +22,16 @@
namespace media { namespace media {
D3D11PictureBuffer::D3D11PictureBuffer( D3D11PictureBuffer::D3D11PictureBuffer(
ComD3D11Texture2D texture,
std::unique_ptr<Texture2DWrapper> texture_wrapper, std::unique_ptr<Texture2DWrapper> texture_wrapper,
gfx::Size size, gfx::Size size,
size_t level) size_t level)
: texture_wrapper_(std::move(texture_wrapper)), : texture_(std::move(texture)),
texture_wrapper_(std::move(texture_wrapper)),
size_(size), size_(size),
level_(level) {} level_(level) {}
D3D11PictureBuffer::~D3D11PictureBuffer() { D3D11PictureBuffer::~D3D11PictureBuffer() {
// TODO(liberato): post destruction of |gpu_resources_| to the gpu thread.
} }
bool D3D11PictureBuffer::Init(GetCommandBufferHelperCB get_helper_cb, bool D3D11PictureBuffer::Init(GetCommandBufferHelperCB get_helper_cb,
...@@ -42,7 +43,7 @@ bool D3D11PictureBuffer::Init(GetCommandBufferHelperCB get_helper_cb, ...@@ -42,7 +43,7 @@ bool D3D11PictureBuffer::Init(GetCommandBufferHelperCB get_helper_cb,
view_desc.ViewDimension = D3D11_VDOV_DIMENSION_TEXTURE2D; view_desc.ViewDimension = D3D11_VDOV_DIMENSION_TEXTURE2D;
view_desc.Texture2D.ArraySlice = (UINT)level_; view_desc.Texture2D.ArraySlice = (UINT)level_;
if (!texture_wrapper_->Init(std::move(get_helper_cb), level_, size_)) { if (!texture_wrapper_->Init(std::move(get_helper_cb))) {
MEDIA_LOG(ERROR, media_log) << "Failed to Initialize the wrapper"; MEDIA_LOG(ERROR, media_log) << "Failed to Initialize the wrapper";
return false; return false;
} }
...@@ -59,11 +60,11 @@ bool D3D11PictureBuffer::Init(GetCommandBufferHelperCB get_helper_cb, ...@@ -59,11 +60,11 @@ bool D3D11PictureBuffer::Init(GetCommandBufferHelperCB get_helper_cb,
} }
bool D3D11PictureBuffer::ProcessTexture(MailboxHolderArray* mailbox_dest) { bool D3D11PictureBuffer::ProcessTexture(MailboxHolderArray* mailbox_dest) {
return texture_wrapper_->ProcessTexture(this, mailbox_dest); return texture_wrapper_->ProcessTexture(Texture(), level_, mailbox_dest);
} }
ComD3D11Texture2D D3D11PictureBuffer::Texture() const { ComD3D11Texture2D D3D11PictureBuffer::Texture() const {
return texture_wrapper_->Texture(); return texture_;
} }
} // namespace media } // namespace media
...@@ -49,7 +49,8 @@ class MEDIA_GPU_EXPORT D3D11PictureBuffer ...@@ -49,7 +49,8 @@ class MEDIA_GPU_EXPORT D3D11PictureBuffer
// |texture_wrapper| is responsible for controlling mailbox access to // |texture_wrapper| is responsible for controlling mailbox access to
// the ID3D11Texture2D, // the ID3D11Texture2D,
// |level| is the picturebuffer index inside the Array-type ID3D11Texture2D. // |level| is the picturebuffer index inside the Array-type ID3D11Texture2D.
D3D11PictureBuffer(std::unique_ptr<Texture2DWrapper> texture_wrapper, D3D11PictureBuffer(ComD3D11Texture2D texture,
std::unique_ptr<Texture2DWrapper> texture_wrapper,
gfx::Size size, gfx::Size size,
size_t level); size_t level);
...@@ -85,6 +86,7 @@ class MEDIA_GPU_EXPORT D3D11PictureBuffer ...@@ -85,6 +86,7 @@ class MEDIA_GPU_EXPORT D3D11PictureBuffer
~D3D11PictureBuffer(); ~D3D11PictureBuffer();
friend class base::RefCountedThreadSafe<D3D11PictureBuffer>; friend class base::RefCountedThreadSafe<D3D11PictureBuffer>;
ComD3D11Texture2D texture_;
std::unique_ptr<Texture2DWrapper> texture_wrapper_; std::unique_ptr<Texture2DWrapper> texture_wrapper_;
gfx::Size size_; gfx::Size size_;
bool in_picture_use_ = false; bool in_picture_use_ = false;
......
...@@ -91,17 +91,15 @@ std::unique_ptr<Texture2DWrapper> TextureSelector::CreateTextureWrapper( ...@@ -91,17 +91,15 @@ std::unique_ptr<Texture2DWrapper> TextureSelector::CreateTextureWrapper(
ComD3D11Device device, ComD3D11Device device,
ComD3D11VideoDevice video_device, ComD3D11VideoDevice video_device,
ComD3D11DeviceContext device_context, ComD3D11DeviceContext device_context,
ComD3D11Texture2D input_texture,
gfx::Size size) { gfx::Size size) {
// TODO(liberato): If the output format is rgb, then create a pbuffer wrapper. // TODO(liberato): If the output format is rgb, then create a pbuffer wrapper.
return std::make_unique<DefaultTexture2DWrapper>(input_texture); return std::make_unique<DefaultTexture2DWrapper>(size);
} }
std::unique_ptr<Texture2DWrapper> CopyTextureSelector::CreateTextureWrapper( std::unique_ptr<Texture2DWrapper> CopyTextureSelector::CreateTextureWrapper(
ComD3D11Device device, ComD3D11Device device,
ComD3D11VideoDevice video_device, ComD3D11VideoDevice video_device,
ComD3D11DeviceContext device_context, ComD3D11DeviceContext device_context,
ComD3D11Texture2D input_texture,
gfx::Size size) { gfx::Size size) {
D3D11_TEXTURE2D_DESC texture_desc = {}; D3D11_TEXTURE2D_DESC texture_desc = {};
texture_desc.MipLevels = 1; texture_desc.MipLevels = 1;
...@@ -127,9 +125,9 @@ std::unique_ptr<Texture2DWrapper> CopyTextureSelector::CreateTextureWrapper( ...@@ -127,9 +125,9 @@ std::unique_ptr<Texture2DWrapper> CopyTextureSelector::CreateTextureWrapper(
return nullptr; return nullptr;
return std::make_unique<CopyingTexture2DWrapper>( return std::make_unique<CopyingTexture2DWrapper>(
std::make_unique<DefaultTexture2DWrapper>(out_texture), size, std::make_unique<DefaultTexture2DWrapper>(size),
std::make_unique<VideoProcessorProxy>(video_device, device_context), std::make_unique<VideoProcessorProxy>(video_device, device_context),
input_texture); out_texture);
} }
} // namespace media } // namespace media
...@@ -37,7 +37,6 @@ class MEDIA_GPU_EXPORT TextureSelector { ...@@ -37,7 +37,6 @@ class MEDIA_GPU_EXPORT TextureSelector {
ComD3D11Device device, ComD3D11Device device,
ComD3D11VideoDevice video_device, ComD3D11VideoDevice video_device,
ComD3D11DeviceContext, ComD3D11DeviceContext,
ComD3D11Texture2D input_texture,
gfx::Size size); gfx::Size size);
VideoPixelFormat PixelFormat() { return pixel_format_; } VideoPixelFormat PixelFormat() { return pixel_format_; }
...@@ -64,7 +63,6 @@ class MEDIA_GPU_EXPORT CopyTextureSelector : public TextureSelector { ...@@ -64,7 +63,6 @@ class MEDIA_GPU_EXPORT CopyTextureSelector : public TextureSelector {
ComD3D11Device device, ComD3D11Device device,
ComD3D11VideoDevice video_device, ComD3D11VideoDevice video_device,
ComD3D11DeviceContext, ComD3D11DeviceContext,
ComD3D11Texture2D input_texture,
gfx::Size size) override; gfx::Size size) override;
private: private:
......
...@@ -8,32 +8,38 @@ ...@@ -8,32 +8,38 @@
#include "gpu/command_buffer/service/mailbox_manager.h" #include "gpu/command_buffer/service/mailbox_manager.h"
#include "media/gpu/windows/return_on_failure.h" #include "media/gpu/windows/return_on_failure.h"
#include "ui/gl/gl_image.h"
namespace media { namespace media {
Texture2DWrapper::Texture2DWrapper(ComD3D11Texture2D texture) Texture2DWrapper::Texture2DWrapper() = default;
: texture_(texture) {}
Texture2DWrapper::~Texture2DWrapper() {} Texture2DWrapper::~Texture2DWrapper() = default;
const ComD3D11Texture2D Texture2DWrapper::Texture() const { DefaultTexture2DWrapper::DefaultTexture2DWrapper(const gfx::Size& size)
return texture_; : size_(size) {}
}
DefaultTexture2DWrapper::DefaultTexture2DWrapper(ComD3D11Texture2D texture) DefaultTexture2DWrapper::~DefaultTexture2DWrapper() = default;
: Texture2DWrapper(texture) {}
DefaultTexture2DWrapper::~DefaultTexture2DWrapper() {}
bool DefaultTexture2DWrapper::ProcessTexture(const D3D11PictureBuffer* owner_pb, bool DefaultTexture2DWrapper::ProcessTexture(ComD3D11Texture2D texture,
size_t array_slice,
MailboxHolderArray* mailbox_dest) { MailboxHolderArray* mailbox_dest) {
// TODO(liberato): When |gpu_resources_| is a SB<>, it's okay to post and
// forget this call. It will still be ordered properly with respect to any
// access on the gpu main thread.
// TODO(liberato): Would be nice if SB<> knew how to post and reply, so that
// we could get the error code back.
auto result = gpu_resources_->PushNewTexture(std::move(texture), array_slice);
if (!result.IsOk())
return false;
for (size_t i = 0; i < VideoFrame::kMaxPlanes; i++) for (size_t i = 0; i < VideoFrame::kMaxPlanes; i++)
(*mailbox_dest)[i] = mailbox_holders_[i]; (*mailbox_dest)[i] = mailbox_holders_[i];
return true; return true;
} }
bool DefaultTexture2DWrapper::Init(GetCommandBufferHelperCB get_helper_cb, bool DefaultTexture2DWrapper::Init(GetCommandBufferHelperCB get_helper_cb) {
size_t array_slice,
gfx::Size size) {
gpu_resources_ = std::make_unique<GpuResources>(); gpu_resources_ = std::make_unique<GpuResources>();
if (!gpu_resources_) if (!gpu_resources_)
return false; return false;
...@@ -55,11 +61,11 @@ bool DefaultTexture2DWrapper::Init(GetCommandBufferHelperCB get_helper_cb, ...@@ -55,11 +61,11 @@ bool DefaultTexture2DWrapper::Init(GetCommandBufferHelperCB get_helper_cb,
// would create the texture with KEYED_MUTEX and NTHANDLE, then send along // would create the texture with KEYED_MUTEX and NTHANDLE, then send along
// 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.
return gpu_resources_->Init(std::move(get_helper_cb), array_slice, // TODO(liberato): the out param would be handled similarly to
std::move(mailboxes), GL_TEXTURE_EXTERNAL_OES, // CodecImageHolder when we add a pool.
size, Texture(), textures_per_picture); return gpu_resources_->Init(std::move(get_helper_cb), std::move(mailboxes),
GL_TEXTURE_EXTERNAL_OES, size_,
return true; textures_per_picture);
} }
DefaultTexture2DWrapper::GpuResources::GpuResources() {} DefaultTexture2DWrapper::GpuResources::GpuResources() {}
...@@ -73,11 +79,9 @@ DefaultTexture2DWrapper::GpuResources::~GpuResources() { ...@@ -73,11 +79,9 @@ DefaultTexture2DWrapper::GpuResources::~GpuResources() {
bool DefaultTexture2DWrapper::GpuResources::Init( bool DefaultTexture2DWrapper::GpuResources::Init(
GetCommandBufferHelperCB get_helper_cb, GetCommandBufferHelperCB get_helper_cb,
int array_slice,
const std::vector<gpu::Mailbox> mailboxes, const std::vector<gpu::Mailbox> mailboxes,
GLenum target, GLenum target,
gfx::Size size, gfx::Size size,
ComD3D11Texture2D angle_texture,
int textures_per_picture) { int textures_per_picture) {
helper_ = get_helper_cb.Run(); helper_ = get_helper_cb.Run();
...@@ -109,8 +113,7 @@ bool DefaultTexture2DWrapper::GpuResources::Init( ...@@ -109,8 +113,7 @@ bool DefaultTexture2DWrapper::GpuResources::Init(
// TODO(liberato): for tests, it will be destroyed pretty much at the end of // 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 // this function unless |helper_| retains it. Also, this won't work if we
// have a FakeCommandBufferHelper since the service IDs aren't meaningful. // have a FakeCommandBufferHelper since the service IDs aren't meaningful.
scoped_refptr<gl::GLImage> gl_image = 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]);
...@@ -141,33 +144,47 @@ bool DefaultTexture2DWrapper::GpuResources::Init( ...@@ -141,33 +144,47 @@ bool DefaultTexture2DWrapper::GpuResources::Init(
producer_attributes); producer_attributes);
RETURN_ON_FAILURE(result, "Could not create stream", false); RETURN_ON_FAILURE(result, "Could not create stream", false);
EGLAttrib frame_attributes[] = { // Note that this is valid as long as |gl_image_| is valid; it is
EGL_D3D_TEXTURE_SUBRESOURCE_ID_ANGLE, // what deletes the stream.
array_slice, stream_ = stream;
EGL_NONE,
};
result = eglStreamPostD3DTextureANGLE(egl_display, stream,
static_cast<void*>(angle_texture.Get()),
frame_attributes);
RETURN_ON_FAILURE(result, "Could not post texture", false);
result = eglStreamConsumerAcquireKHR(egl_display, stream);
RETURN_ON_FAILURE(result, "Could not post acquire stream", false);
gl::GLImageDXGI* gl_image_dxgi =
static_cast<gl::GLImageDXGI*>(gl_image.get());
gl_image_dxgi->SetTexture(angle_texture, array_slice);
// Bind the image to each texture. // Bind the image to each texture.
for (size_t texture_idx = 0; texture_idx < service_ids_.size(); for (size_t texture_idx = 0; texture_idx < service_ids_.size();
texture_idx++) { texture_idx++) {
helper_->BindImage(service_ids_[texture_idx], gl_image.get(), helper_->BindImage(service_ids_[texture_idx], gl_image_.get(),
false /* client_managed */); false /* client_managed */);
} }
return true; return true;
} }
MediaError DefaultTexture2DWrapper::GpuResources::PushNewTexture(
ComD3D11Texture2D texture,
size_t array_slice) {
if (!helper_ || !helper_->MakeContextCurrent())
return MediaError(ErrorCode::kCannotMakeContextCurrent);
// Notify |gl_image_| that it has a new texture.
gl_image_->SetTexture(texture, array_slice);
// Notify angle that it has a new texture.
EGLAttrib frame_attributes[] = {
EGL_D3D_TEXTURE_SUBRESOURCE_ID_ANGLE,
array_slice,
EGL_NONE,
};
EGLDisplay egl_display = gl::GLSurfaceEGL::GetHardwareDisplay();
if (!eglStreamPostD3DTextureANGLE(egl_display, stream_,
static_cast<void*>(texture.Get()),
frame_attributes)) {
return MediaError(ErrorCode::kCouldNotPostTexture);
}
if (!eglStreamConsumerAcquireKHR(egl_display, stream_))
return MediaError(ErrorCode::kCouldNotPostAcquireStream);
return MediaError::Ok();
}
} // namespace media } // namespace media
...@@ -12,6 +12,7 @@ ...@@ -12,6 +12,7 @@
#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/base/media_error.h"
#include "media/base/video_frame.h" #include "media/base/video_frame.h"
#include "media/gpu/command_buffer_helper.h" #include "media/gpu/command_buffer_helper.h"
#include "media/gpu/media_gpu_export.h" #include "media/gpu/media_gpu_export.h"
...@@ -29,44 +30,38 @@ using MailboxHolderArray = gpu::MailboxHolder[VideoFrame::kMaxPlanes]; ...@@ -29,44 +30,38 @@ using MailboxHolderArray = gpu::MailboxHolder[VideoFrame::kMaxPlanes];
using GetCommandBufferHelperCB = using GetCommandBufferHelperCB =
base::RepeatingCallback<CommandBufferHelperPtr()>; base::RepeatingCallback<CommandBufferHelperPtr()>;
class D3D11PictureBuffer;
// Support different strategies for processing pictures - some may need copying, // Support different strategies for processing pictures - some may need copying,
// for example. // for example. Each wrapper owns the resources for a single texture, so it's
// up to you not to re-use a wrapper for a second image before a previously
// processed image is no longer needed.
class MEDIA_GPU_EXPORT Texture2DWrapper { class MEDIA_GPU_EXPORT Texture2DWrapper {
public: public:
Texture2DWrapper(ComD3D11Texture2D texture); Texture2DWrapper();
virtual ~Texture2DWrapper(); virtual ~Texture2DWrapper();
virtual const ComD3D11Texture2D Texture() const; // Initialize the wrapper.
virtual bool Init(GetCommandBufferHelperCB get_helper_cb) = 0;
// This pointer can be raw, since each Texture2DWrapper is directly owned
// by the D3D11PictureBuffer through a unique_ptr.
virtual bool ProcessTexture(const D3D11PictureBuffer* owner_pb,
MailboxHolderArray* mailbox_dest) = 0;
// |array_slice| Tells us which array index of the array-type Texture2D
// we should be using - if it is not an array-type, |array_slice| is 0.
virtual bool Init(GetCommandBufferHelperCB get_helper_cb,
size_t array_slice,
gfx::Size size) = 0;
private: // Import |texture|, |array_slice| and return the mailbox(es) that can be
ComD3D11Texture2D texture_; // used to refer to it.
virtual bool ProcessTexture(ComD3D11Texture2D texture,
size_t array_slice,
MailboxHolderArray* mailbox_dest_out) = 0;
}; };
// The default texture wrapper that uses GPUResources to talk to hardware // The default texture wrapper that uses GPUResources to talk to hardware
// on behalf of a Texture2D. // on behalf of a Texture2D. Each DefaultTexture2DWrapper owns GL textures
// that it uses to bind the provided input texture. Thus, one needs one wrapper
// instance for each concurrently outstanding texture.
class MEDIA_GPU_EXPORT DefaultTexture2DWrapper : public Texture2DWrapper { class MEDIA_GPU_EXPORT DefaultTexture2DWrapper : public Texture2DWrapper {
public: public:
DefaultTexture2DWrapper(ComD3D11Texture2D texture); DefaultTexture2DWrapper(const gfx::Size& size);
~DefaultTexture2DWrapper() override; ~DefaultTexture2DWrapper() override;
bool Init(GetCommandBufferHelperCB get_helper_cb, bool Init(GetCommandBufferHelperCB get_helper_cb) override;
size_t array_slice,
gfx::Size size) override;
bool ProcessTexture(const D3D11PictureBuffer* owner_pb, bool ProcessTexture(ComD3D11Texture2D texture,
size_t array_slice,
MailboxHolderArray* mailbox_dest) override; MailboxHolderArray* mailbox_dest) override;
private: private:
...@@ -80,21 +75,25 @@ class MEDIA_GPU_EXPORT DefaultTexture2DWrapper : public Texture2DWrapper { ...@@ -80,21 +75,25 @@ class MEDIA_GPU_EXPORT DefaultTexture2DWrapper : public Texture2DWrapper {
~GpuResources(); ~GpuResources();
bool Init(GetCommandBufferHelperCB get_helper_cb, bool Init(GetCommandBufferHelperCB get_helper_cb,
int array_slice,
const std::vector<gpu::Mailbox> mailboxes, const std::vector<gpu::Mailbox> mailboxes,
GLenum target, GLenum target,
gfx::Size size, gfx::Size size,
ComD3D11Texture2D angle_texture,
int textures_per_picture); int textures_per_picture);
// Push a new |texture|, |array_slice| to |gl_image_|.
MediaError PushNewTexture(ComD3D11Texture2D texture, size_t array_slice);
std::vector<uint32_t> service_ids_; std::vector<uint32_t> service_ids_;
private: private:
scoped_refptr<CommandBufferHelper> helper_; scoped_refptr<CommandBufferHelper> helper_;
scoped_refptr<gl::GLImageDXGI> gl_image_;
EGLStreamKHR stream_;
DISALLOW_COPY_AND_ASSIGN(GpuResources); DISALLOW_COPY_AND_ASSIGN(GpuResources);
}; };
gfx::Size size_;
std::unique_ptr<GpuResources> gpu_resources_; std::unique_ptr<GpuResources> gpu_resources_;
MailboxHolderArray mailbox_holders_; MailboxHolderArray mailbox_holders_;
}; };
......
...@@ -675,14 +675,14 @@ void D3D11VideoDecoder::CreatePictureBuffers() { ...@@ -675,14 +675,14 @@ void D3D11VideoDecoder::CreatePictureBuffers() {
// Create each picture buffer. // Create each picture buffer.
for (size_t i = 0; i < D3D11DecoderConfigurator::BUFFER_COUNT; i++) { for (size_t i = 0; i < D3D11DecoderConfigurator::BUFFER_COUNT; i++) {
auto tex_wrapper = texture_selector_->CreateTextureWrapper( auto tex_wrapper = texture_selector_->CreateTextureWrapper(
device_, video_device_, device_context_, in_texture, size); device_, video_device_, device_context_, size);
if (!tex_wrapper) { if (!tex_wrapper) {
NotifyError("Unable to allocate a texture for a CopyingTexture2DWrapper"); NotifyError("Unable to allocate a texture for a CopyingTexture2DWrapper");
return; return;
} }
picture_buffers_.push_back( picture_buffers_.push_back(
new D3D11PictureBuffer(std::move(tex_wrapper), size, i)); new D3D11PictureBuffer(in_texture, std::move(tex_wrapper), size, i));
if (!picture_buffers_[i]->Init(get_helper_cb_, video_device_, if (!picture_buffers_[i]->Init(get_helper_cb_, video_device_,
decoder_configurator_->DecoderGuid(), decoder_configurator_->DecoderGuid(),
media_log_->Clone())) { media_log_->Clone())) {
......
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