| Index: content/renderer/media/renderer_gpu_video_accelerator_factories.cc
|
| diff --git a/content/renderer/media/renderer_gpu_video_decoder_factories.cc b/content/renderer/media/renderer_gpu_video_accelerator_factories.cc
|
| similarity index 54%
|
| rename from content/renderer/media/renderer_gpu_video_decoder_factories.cc
|
| rename to content/renderer/media/renderer_gpu_video_accelerator_factories.cc
|
| index d33e5901b2af82388a5364012575a4c9cf109e4e..a99bea6c8bcd125dddea8da283cffc9ddd543f4a 100644
|
| --- a/content/renderer/media/renderer_gpu_video_decoder_factories.cc
|
| +++ b/content/renderer/media/renderer_gpu_video_accelerator_factories.cc
|
| @@ -2,7 +2,7 @@
|
| // Use of this source code is governed by a BSD-style license that can be
|
| // found in the LICENSE file.
|
|
|
| -#include "content/renderer/media/renderer_gpu_video_decoder_factories.h"
|
| +#include "content/renderer/media/renderer_gpu_video_accelerator_factories.h"
|
|
|
| #include <GLES2/gl2.h>
|
| #include <GLES2/gl2ext.h>
|
| @@ -17,8 +17,8 @@
|
|
|
| namespace content {
|
|
|
| -RendererGpuVideoDecoderFactories::~RendererGpuVideoDecoderFactories() {}
|
| -RendererGpuVideoDecoderFactories::RendererGpuVideoDecoderFactories(
|
| +RendererGpuVideoAcceleratorFactories::~RendererGpuVideoAcceleratorFactories() {}
|
| +RendererGpuVideoAcceleratorFactories::RendererGpuVideoAcceleratorFactories(
|
| GpuChannelHost* gpu_channel_host,
|
| const scoped_refptr<base::MessageLoopProxy>& message_loop,
|
| WebGraphicsContext3DCommandBufferImpl* context)
|
| @@ -28,32 +28,37 @@ RendererGpuVideoDecoderFactories::RendererGpuVideoDecoderFactories(
|
| aborted_waiter_(true, false),
|
| message_loop_async_waiter_(false, false),
|
| render_thread_async_waiter_(false, false) {
|
| + // |context| is only required to support HW-accelerated decode.
|
| + if (!context)
|
| + return;
|
| +
|
| if (message_loop_->BelongsToCurrentThread()) {
|
| AsyncGetContext(context);
|
| message_loop_async_waiter_.Reset();
|
| return;
|
| }
|
| // Wait for the context to be acquired.
|
| - message_loop_->PostTask(FROM_HERE, base::Bind(
|
| - &RendererGpuVideoDecoderFactories::AsyncGetContext,
|
| - // Unretained to avoid ref/deref'ing |*this|, which is not yet stored in a
|
| - // scoped_refptr. Safe because the Wait() below keeps us alive until this
|
| - // task completes.
|
| - base::Unretained(this),
|
| - // OK to pass raw because the pointee is only deleted on the compositor
|
| - // thread, and only as the result of a PostTask from the render thread
|
| - // which can only happen after this function returns, so our PostTask will
|
| - // run first.
|
| - context));
|
| + message_loop_->PostTask(
|
| + FROM_HERE,
|
| + base::Bind(&RendererGpuVideoAcceleratorFactories::AsyncGetContext,
|
| + // Unretained to avoid ref/deref'ing |*this|, which is not yet
|
| + // stored in a scoped_refptr. Safe because the Wait() below
|
| + // keeps us alive until this task completes.
|
| + base::Unretained(this),
|
| + // OK to pass raw because the pointee is only deleted on the
|
| + // compositor thread, and only as the result of a PostTask from
|
| + // the render thread which can only happen after this function
|
| + // returns, so our PostTask will run first.
|
| + context));
|
| message_loop_async_waiter_.Wait();
|
| }
|
|
|
| -RendererGpuVideoDecoderFactories::RendererGpuVideoDecoderFactories()
|
| +RendererGpuVideoAcceleratorFactories::RendererGpuVideoAcceleratorFactories()
|
| : aborted_waiter_(true, false),
|
| message_loop_async_waiter_(false, false),
|
| render_thread_async_waiter_(false, false) {}
|
|
|
| -void RendererGpuVideoDecoderFactories::AsyncGetContext(
|
| +void RendererGpuVideoAcceleratorFactories::AsyncGetContext(
|
| WebGraphicsContext3DCommandBufferImpl* context) {
|
| context_ = context->AsWeakPtr();
|
| if (context_.get()) {
|
| @@ -66,20 +71,23 @@ void RendererGpuVideoDecoderFactories::AsyncGetContext(
|
| message_loop_async_waiter_.Signal();
|
| }
|
|
|
| -media::VideoDecodeAccelerator*
|
| -RendererGpuVideoDecoderFactories::CreateVideoDecodeAccelerator(
|
| +scoped_ptr<media::VideoDecodeAccelerator>
|
| +RendererGpuVideoAcceleratorFactories::CreateVideoDecodeAccelerator(
|
| media::VideoCodecProfile profile,
|
| media::VideoDecodeAccelerator::Client* client) {
|
| if (message_loop_->BelongsToCurrentThread()) {
|
| AsyncCreateVideoDecodeAccelerator(profile, client);
|
| message_loop_async_waiter_.Reset();
|
| - return vda_.release();
|
| + return vda_.Pass();
|
| }
|
| // The VDA is returned in the vda_ member variable by the
|
| // AsyncCreateVideoDecodeAccelerator() function.
|
| - message_loop_->PostTask(FROM_HERE, base::Bind(
|
| - &RendererGpuVideoDecoderFactories::AsyncCreateVideoDecodeAccelerator,
|
| - this, profile, client));
|
| + message_loop_->PostTask(FROM_HERE,
|
| + base::Bind(&RendererGpuVideoAcceleratorFactories::
|
| + AsyncCreateVideoDecodeAccelerator,
|
| + this,
|
| + profile,
|
| + client));
|
|
|
| base::WaitableEvent* objects[] = {&aborted_waiter_,
|
| &message_loop_async_waiter_};
|
| @@ -87,17 +95,49 @@ RendererGpuVideoDecoderFactories::CreateVideoDecodeAccelerator(
|
| // If we are aborting and the VDA is created by the
|
| // AsyncCreateVideoDecodeAccelerator() function later we need to ensure
|
| // that it is destroyed on the same thread.
|
| - message_loop_->PostTask(FROM_HERE, base::Bind(
|
| - &RendererGpuVideoDecoderFactories::AsyncDestroyVideoDecodeAccelerator,
|
| - this));
|
| - return NULL;
|
| + message_loop_->PostTask(FROM_HERE,
|
| + base::Bind(&RendererGpuVideoAcceleratorFactories::
|
| + AsyncDestroyVideoDecodeAccelerator,
|
| + this));
|
| + return scoped_ptr<media::VideoDecodeAccelerator>();
|
| }
|
| - return vda_.release();
|
| + return vda_.Pass();
|
| }
|
|
|
| -void RendererGpuVideoDecoderFactories::AsyncCreateVideoDecodeAccelerator(
|
| - media::VideoCodecProfile profile,
|
| - media::VideoDecodeAccelerator::Client* client) {
|
| +scoped_ptr<media::VideoEncodeAccelerator>
|
| +RendererGpuVideoAcceleratorFactories::CreateVideoEncodeAccelerator(
|
| + media::VideoEncodeAccelerator::Client* client) {
|
| + if (message_loop_->BelongsToCurrentThread()) {
|
| + AsyncCreateVideoEncodeAccelerator(client);
|
| + message_loop_async_waiter_.Reset();
|
| + return vea_.Pass();
|
| + }
|
| + // The VEA is returned in the vea_ member variable by the
|
| + // AsyncCreateVideoEncodeAccelerator() function.
|
| + message_loop_->PostTask(FROM_HERE,
|
| + base::Bind(&RendererGpuVideoAcceleratorFactories::
|
| + AsyncCreateVideoEncodeAccelerator,
|
| + this,
|
| + client));
|
| +
|
| + base::WaitableEvent* objects[] = {&aborted_waiter_,
|
| + &message_loop_async_waiter_};
|
| + if (base::WaitableEvent::WaitMany(objects, arraysize(objects)) == 0) {
|
| + // If we are aborting and the VDA is created by the
|
| + // AsyncCreateVideoEncodeAccelerator() function later we need to ensure
|
| + // that it is destroyed on the same thread.
|
| + message_loop_->PostTask(FROM_HERE,
|
| + base::Bind(&RendererGpuVideoAcceleratorFactories::
|
| + AsyncDestroyVideoEncodeAccelerator,
|
| + this));
|
| + return scoped_ptr<media::VideoEncodeAccelerator>();
|
| + }
|
| + return vea_.Pass();
|
| +}
|
| +
|
| +void RendererGpuVideoAcceleratorFactories::AsyncCreateVideoDecodeAccelerator(
|
| + media::VideoCodecProfile profile,
|
| + media::VideoDecodeAccelerator::Client* client) {
|
| DCHECK(message_loop_->BelongsToCurrentThread());
|
|
|
| if (context_.get() && context_->GetCommandBufferProxy()) {
|
| @@ -107,8 +147,17 @@ void RendererGpuVideoDecoderFactories::AsyncCreateVideoDecodeAccelerator(
|
| message_loop_async_waiter_.Signal();
|
| }
|
|
|
| -uint32 RendererGpuVideoDecoderFactories::CreateTextures(
|
| - int32 count, const gfx::Size& size,
|
| +void RendererGpuVideoAcceleratorFactories::AsyncCreateVideoEncodeAccelerator(
|
| + media::VideoEncodeAccelerator::Client* client) {
|
| + DCHECK(message_loop_->BelongsToCurrentThread());
|
| +
|
| + vea_ = gpu_channel_host_->CreateVideoEncoder(client).Pass();
|
| + message_loop_async_waiter_.Signal();
|
| +}
|
| +
|
| +uint32 RendererGpuVideoAcceleratorFactories::CreateTextures(
|
| + int32 count,
|
| + const gfx::Size& size,
|
| std::vector<uint32>* texture_ids,
|
| std::vector<gpu::Mailbox>* texture_mailboxes,
|
| uint32 texture_target) {
|
| @@ -121,9 +170,14 @@ uint32 RendererGpuVideoDecoderFactories::CreateTextures(
|
| message_loop_async_waiter_.Reset();
|
| return sync_point;
|
| }
|
| - message_loop_->PostTask(FROM_HERE, base::Bind(
|
| - &RendererGpuVideoDecoderFactories::AsyncCreateTextures, this,
|
| - count, size, texture_target, &sync_point));
|
| + message_loop_->PostTask(
|
| + FROM_HERE,
|
| + base::Bind(&RendererGpuVideoAcceleratorFactories::AsyncCreateTextures,
|
| + this,
|
| + count,
|
| + size,
|
| + texture_target,
|
| + &sync_point));
|
|
|
| base::WaitableEvent* objects[] = {&aborted_waiter_,
|
| &message_loop_async_waiter_};
|
| @@ -134,8 +188,10 @@ uint32 RendererGpuVideoDecoderFactories::CreateTextures(
|
| return sync_point;
|
| }
|
|
|
| -void RendererGpuVideoDecoderFactories::AsyncCreateTextures(
|
| - int32 count, const gfx::Size& size, uint32 texture_target,
|
| +void RendererGpuVideoAcceleratorFactories::AsyncCreateTextures(
|
| + int32 count,
|
| + const gfx::Size& size,
|
| + uint32 texture_target,
|
| uint32* sync_point) {
|
| DCHECK(message_loop_->BelongsToCurrentThread());
|
| DCHECK(texture_target);
|
| @@ -157,8 +213,15 @@ void RendererGpuVideoDecoderFactories::AsyncCreateTextures(
|
| gles2->TexParameteri(texture_target, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
|
| gles2->TexParameteri(texture_target, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
|
| if (texture_target == GL_TEXTURE_2D) {
|
| - gles2->TexImage2D(texture_target, 0, GL_RGBA, size.width(), size.height(),
|
| - 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
|
| + gles2->TexImage2D(texture_target,
|
| + 0,
|
| + GL_RGBA,
|
| + size.width(),
|
| + size.height(),
|
| + 0,
|
| + GL_RGBA,
|
| + GL_UNSIGNED_BYTE,
|
| + NULL);
|
| }
|
| gles2->GenMailboxCHROMIUM(created_texture_mailboxes_[i].name);
|
| gles2->ProduceTextureCHROMIUM(texture_target,
|
| @@ -175,16 +238,20 @@ void RendererGpuVideoDecoderFactories::AsyncCreateTextures(
|
| message_loop_async_waiter_.Signal();
|
| }
|
|
|
| -void RendererGpuVideoDecoderFactories::DeleteTexture(uint32 texture_id) {
|
| +void RendererGpuVideoAcceleratorFactories::DeleteTexture(uint32 texture_id) {
|
| if (message_loop_->BelongsToCurrentThread()) {
|
| AsyncDeleteTexture(texture_id);
|
| return;
|
| }
|
| - message_loop_->PostTask(FROM_HERE, base::Bind(
|
| - &RendererGpuVideoDecoderFactories::AsyncDeleteTexture, this, texture_id));
|
| + message_loop_->PostTask(
|
| + FROM_HERE,
|
| + base::Bind(&RendererGpuVideoAcceleratorFactories::AsyncDeleteTexture,
|
| + this,
|
| + texture_id));
|
| }
|
|
|
| -void RendererGpuVideoDecoderFactories::AsyncDeleteTexture(uint32 texture_id) {
|
| +void RendererGpuVideoAcceleratorFactories::AsyncDeleteTexture(
|
| + uint32 texture_id) {
|
| DCHECK(message_loop_->BelongsToCurrentThread());
|
| if (!context_.get())
|
| return;
|
| @@ -194,23 +261,25 @@ void RendererGpuVideoDecoderFactories::AsyncDeleteTexture(uint32 texture_id) {
|
| DCHECK_EQ(gles2->GetError(), static_cast<GLenum>(GL_NO_ERROR));
|
| }
|
|
|
| -void RendererGpuVideoDecoderFactories::WaitSyncPoint(uint32 sync_point) {
|
| +void RendererGpuVideoAcceleratorFactories::WaitSyncPoint(uint32 sync_point) {
|
| if (message_loop_->BelongsToCurrentThread()) {
|
| AsyncWaitSyncPoint(sync_point);
|
| message_loop_async_waiter_.Reset();
|
| return;
|
| }
|
|
|
| - message_loop_->PostTask(FROM_HERE, base::Bind(
|
| - &RendererGpuVideoDecoderFactories::AsyncWaitSyncPoint,
|
| - this,
|
| - sync_point));
|
| + message_loop_->PostTask(
|
| + FROM_HERE,
|
| + base::Bind(&RendererGpuVideoAcceleratorFactories::AsyncWaitSyncPoint,
|
| + this,
|
| + sync_point));
|
| base::WaitableEvent* objects[] = {&aborted_waiter_,
|
| &message_loop_async_waiter_};
|
| base::WaitableEvent::WaitMany(objects, arraysize(objects));
|
| }
|
|
|
| -void RendererGpuVideoDecoderFactories::AsyncWaitSyncPoint(uint32 sync_point) {
|
| +void RendererGpuVideoAcceleratorFactories::AsyncWaitSyncPoint(
|
| + uint32 sync_point) {
|
| DCHECK(message_loop_->BelongsToCurrentThread());
|
| if (!context_) {
|
| message_loop_async_waiter_.Signal();
|
| @@ -222,9 +291,10 @@ void RendererGpuVideoDecoderFactories::AsyncWaitSyncPoint(uint32 sync_point) {
|
| message_loop_async_waiter_.Signal();
|
| }
|
|
|
| -void RendererGpuVideoDecoderFactories::ReadPixels(
|
| - uint32 texture_id, uint32 texture_target, const gfx::Size& size,
|
| - const SkBitmap& pixels) {
|
| +void RendererGpuVideoAcceleratorFactories::ReadPixels(uint32 texture_id,
|
| + uint32 texture_target,
|
| + const gfx::Size& size,
|
| + const SkBitmap& pixels) {
|
| // SkBitmaps use the SkPixelRef object to refcount the underlying pixels.
|
| // Multiple SkBitmaps can share a SkPixelRef instance. We use this to
|
| // ensure that the underlying pixels in the SkBitmap passed in remain valid
|
| @@ -232,9 +302,13 @@ void RendererGpuVideoDecoderFactories::ReadPixels(
|
| read_pixels_bitmap_.setPixelRef(pixels.pixelRef());
|
|
|
| if (!message_loop_->BelongsToCurrentThread()) {
|
| - message_loop_->PostTask(FROM_HERE, base::Bind(
|
| - &RendererGpuVideoDecoderFactories::AsyncReadPixels, this,
|
| - texture_id, texture_target, size));
|
| + message_loop_->PostTask(
|
| + FROM_HERE,
|
| + base::Bind(&RendererGpuVideoAcceleratorFactories::AsyncReadPixels,
|
| + this,
|
| + texture_id,
|
| + texture_target,
|
| + size));
|
| base::WaitableEvent* objects[] = {&aborted_waiter_,
|
| &message_loop_async_waiter_};
|
| if (base::WaitableEvent::WaitMany(objects, arraysize(objects)) == 0)
|
| @@ -246,8 +320,10 @@ void RendererGpuVideoDecoderFactories::ReadPixels(
|
| read_pixels_bitmap_.setPixelRef(NULL);
|
| }
|
|
|
| -void RendererGpuVideoDecoderFactories::AsyncReadPixels(
|
| - uint32 texture_id, uint32 texture_target, const gfx::Size& size) {
|
| +void RendererGpuVideoAcceleratorFactories::AsyncReadPixels(
|
| + uint32 texture_id,
|
| + uint32 texture_target,
|
| + const gfx::Size& size) {
|
| DCHECK(message_loop_->BelongsToCurrentThread());
|
| if (!context_.get()) {
|
| message_loop_async_waiter_.Signal();
|
| @@ -269,25 +345,32 @@ void RendererGpuVideoDecoderFactories::AsyncReadPixels(
|
| GLuint fb;
|
| gles2->GenFramebuffers(1, &fb);
|
| gles2->BindFramebuffer(GL_FRAMEBUFFER, fb);
|
| - gles2->FramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
|
| - texture_target, tmp_texture, 0);
|
| + gles2->FramebufferTexture2D(
|
| + GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, texture_target, tmp_texture, 0);
|
| gles2->PixelStorei(GL_PACK_ALIGNMENT, 4);
|
| - gles2->ReadPixels(0, 0, size.width(), size.height(), GL_BGRA_EXT,
|
| - GL_UNSIGNED_BYTE, read_pixels_bitmap_.pixelRef()->pixels());
|
| + gles2->ReadPixels(0,
|
| + 0,
|
| + size.width(),
|
| + size.height(),
|
| + GL_BGRA_EXT,
|
| + GL_UNSIGNED_BYTE,
|
| + read_pixels_bitmap_.pixelRef()->pixels());
|
| gles2->DeleteFramebuffers(1, &fb);
|
| gles2->DeleteTextures(1, &tmp_texture);
|
| DCHECK_EQ(gles2->GetError(), static_cast<GLenum>(GL_NO_ERROR));
|
| message_loop_async_waiter_.Signal();
|
| }
|
|
|
| -base::SharedMemory* RendererGpuVideoDecoderFactories::CreateSharedMemory(
|
| +base::SharedMemory* RendererGpuVideoAcceleratorFactories::CreateSharedMemory(
|
| size_t size) {
|
| if (main_message_loop_->BelongsToCurrentThread()) {
|
| return ChildThread::current()->AllocateSharedMemory(size);
|
| }
|
| - main_message_loop_->PostTask(FROM_HERE, base::Bind(
|
| - &RendererGpuVideoDecoderFactories::AsyncCreateSharedMemory, this,
|
| - size));
|
| + main_message_loop_->PostTask(
|
| + FROM_HERE,
|
| + base::Bind(&RendererGpuVideoAcceleratorFactories::AsyncCreateSharedMemory,
|
| + this,
|
| + size));
|
|
|
| base::WaitableEvent* objects[] = {&aborted_waiter_,
|
| &render_thread_async_waiter_};
|
| @@ -296,7 +379,8 @@ base::SharedMemory* RendererGpuVideoDecoderFactories::CreateSharedMemory(
|
| return shared_memory_segment_.release();
|
| }
|
|
|
| -void RendererGpuVideoDecoderFactories::AsyncCreateSharedMemory(size_t size) {
|
| +void RendererGpuVideoAcceleratorFactories::AsyncCreateSharedMemory(
|
| + size_t size) {
|
| DCHECK_EQ(base::MessageLoop::current(),
|
| ChildThread::current()->message_loop());
|
|
|
| @@ -306,22 +390,20 @@ void RendererGpuVideoDecoderFactories::AsyncCreateSharedMemory(size_t size) {
|
| }
|
|
|
| scoped_refptr<base::MessageLoopProxy>
|
| -RendererGpuVideoDecoderFactories::GetMessageLoop() {
|
| +RendererGpuVideoAcceleratorFactories::GetMessageLoop() {
|
| return message_loop_;
|
| }
|
|
|
| -void RendererGpuVideoDecoderFactories::Abort() {
|
| - aborted_waiter_.Signal();
|
| -}
|
| +void RendererGpuVideoAcceleratorFactories::Abort() { aborted_waiter_.Signal(); }
|
|
|
| -bool RendererGpuVideoDecoderFactories::IsAborted() {
|
| +bool RendererGpuVideoAcceleratorFactories::IsAborted() {
|
| return aborted_waiter_.IsSignaled();
|
| }
|
|
|
| -scoped_refptr<media::GpuVideoDecoderFactories>
|
| -RendererGpuVideoDecoderFactories::Clone() {
|
| - scoped_refptr<RendererGpuVideoDecoderFactories> factories =
|
| - new RendererGpuVideoDecoderFactories();
|
| +scoped_refptr<RendererGpuVideoAcceleratorFactories>
|
| +RendererGpuVideoAcceleratorFactories::Clone() {
|
| + scoped_refptr<RendererGpuVideoAcceleratorFactories> factories =
|
| + new RendererGpuVideoAcceleratorFactories();
|
| factories->message_loop_ = message_loop_;
|
| factories->main_message_loop_ = main_message_loop_;
|
| factories->gpu_channel_host_ = gpu_channel_host_;
|
| @@ -329,10 +411,18 @@ RendererGpuVideoDecoderFactories::Clone() {
|
| return factories;
|
| }
|
|
|
| -void RendererGpuVideoDecoderFactories::AsyncDestroyVideoDecodeAccelerator() {
|
| +void
|
| +RendererGpuVideoAcceleratorFactories::AsyncDestroyVideoDecodeAccelerator() {
|
| // OK to release because Destroy() will delete the VDA instance.
|
| if (vda_)
|
| vda_.release()->Destroy();
|
| }
|
|
|
| +void
|
| +RendererGpuVideoAcceleratorFactories::AsyncDestroyVideoEncodeAccelerator() {
|
| + // OK to release because Destroy() will delete the VDA instance.
|
| + if (vea_)
|
| + vea_.release()->Destroy();
|
| +}
|
| +
|
| } // namespace content
|
|
|