summaryrefslogtreecommitdiffstats
path: root/content/renderer/media/renderer_gpu_video_decoder_factories.cc
diff options
context:
space:
mode:
Diffstat (limited to 'content/renderer/media/renderer_gpu_video_decoder_factories.cc')
-rw-r--r--content/renderer/media/renderer_gpu_video_decoder_factories.cc144
1 files changed, 56 insertions, 88 deletions
diff --git a/content/renderer/media/renderer_gpu_video_decoder_factories.cc b/content/renderer/media/renderer_gpu_video_decoder_factories.cc
index 1f0e85a..cdd5804 100644
--- a/content/renderer/media/renderer_gpu_video_decoder_factories.cc
+++ b/content/renderer/media/renderer_gpu_video_decoder_factories.cc
@@ -8,12 +8,12 @@
#include <GLES2/gl2ext.h>
#include "base/bind.h"
+#include "base/synchronization/waitable_event.h"
#include "content/common/child_thread.h"
#include "content/common/gpu/client/gpu_channel_host.h"
#include "content/common/gpu/client/webgraphicscontext3d_command_buffer_impl.h"
#include "gpu/command_buffer/client/gles2_implementation.h"
#include "gpu/ipc/command_buffer_proxy.h"
-#include "third_party/skia/include/core/SkPixelRef.h"
namespace content {
@@ -23,14 +23,13 @@ RendererGpuVideoDecoderFactories::RendererGpuVideoDecoderFactories(
const scoped_refptr<base::MessageLoopProxy>& message_loop,
WebGraphicsContext3DCommandBufferImpl* context)
: message_loop_(message_loop),
- gpu_channel_host_(gpu_channel_host),
- aborted_waiter_(true, false),
- async_waiter_(false, false) {
+ gpu_channel_host_(gpu_channel_host) {
if (message_loop_->BelongsToCurrentThread()) {
- AsyncGetContext(context);
+ AsyncGetContext(context, NULL);
return;
}
// Threaded compositor requires us to wait for the context to be acquired.
+ base::WaitableEvent waiter(false, false);
message_loop_->PostTask(FROM_HERE, base::Bind(
&RendererGpuVideoDecoderFactories::AsyncGetContext,
// Unretained to avoid ref/deref'ing |*this|, which is not yet stored in a
@@ -41,12 +40,14 @@ RendererGpuVideoDecoderFactories::RendererGpuVideoDecoderFactories(
// 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));
- async_waiter_.Wait();
+ context,
+ &waiter));
+ waiter.Wait();
}
void RendererGpuVideoDecoderFactories::AsyncGetContext(
- WebGraphicsContext3DCommandBufferImpl* context) {
+ WebGraphicsContext3DCommandBufferImpl* context,
+ base::WaitableEvent* waiter) {
context_ = context->AsWeakPtr();
if (context_) {
if (context_->makeContextCurrent()) {
@@ -55,7 +56,8 @@ void RendererGpuVideoDecoderFactories::AsyncGetContext(
context_->insertEventMarkerEXT("GpuVDAContext3D");
}
}
- async_waiter_.Signal();
+ if (waiter)
+ waiter->Signal();
}
media::VideoDecodeAccelerator*
@@ -63,36 +65,29 @@ RendererGpuVideoDecoderFactories::CreateVideoDecodeAccelerator(
media::VideoCodecProfile profile,
media::VideoDecodeAccelerator::Client* client) {
DCHECK(!message_loop_->BelongsToCurrentThread());
- // The VDA is returned in the vda_ member variable by the
- // AsyncCreateVideoDecodeAccelerator() function.
+ media::VideoDecodeAccelerator* vda = NULL;
+ base::WaitableEvent waiter(false, false);
message_loop_->PostTask(FROM_HERE, base::Bind(
&RendererGpuVideoDecoderFactories::AsyncCreateVideoDecodeAccelerator,
- this, profile, client));
-
- base::WaitableEvent* objects[] = {&aborted_waiter_, &async_waiter_};
- if (base::WaitableEvent::WaitMany(objects, arraysize(objects)) == 0) {
- // 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;
- }
- return vda_.release();
+ this, profile, client, &vda, &waiter));
+ waiter.Wait();
+ return vda;
}
void RendererGpuVideoDecoderFactories::AsyncCreateVideoDecodeAccelerator(
media::VideoCodecProfile profile,
- media::VideoDecodeAccelerator::Client* client) {
+ media::VideoDecodeAccelerator::Client* client,
+ media::VideoDecodeAccelerator** vda,
+ base::WaitableEvent* waiter) {
DCHECK(message_loop_->BelongsToCurrentThread());
-
if (context_ && context_->GetCommandBufferProxy()) {
- vda_.reset(gpu_channel_host_->CreateVideoDecoder(
+ *vda = gpu_channel_host_->CreateVideoDecoder(
context_->GetCommandBufferProxy()->GetRouteID(),
- profile, client));
+ profile, client);
+ } else {
+ *vda = NULL;
}
- async_waiter_.Signal();
+ waiter->Signal();
}
bool RendererGpuVideoDecoderFactories::CreateTextures(
@@ -100,32 +95,31 @@ bool RendererGpuVideoDecoderFactories::CreateTextures(
std::vector<uint32>* texture_ids,
uint32 texture_target) {
DCHECK(!message_loop_->BelongsToCurrentThread());
+ bool success = false;
+ base::WaitableEvent waiter(false, false);
message_loop_->PostTask(FROM_HERE, base::Bind(
&RendererGpuVideoDecoderFactories::AsyncCreateTextures, this,
- count, size, texture_target));
-
- base::WaitableEvent* objects[] = {&aborted_waiter_, &async_waiter_};
- if (base::WaitableEvent::WaitMany(objects, arraysize(objects)) == 0)
- return false;
- texture_ids->swap(created_textures_);
- return true;
+ count, size, texture_ids, texture_target, &success, &waiter));
+ waiter.Wait();
+ return success;
}
void RendererGpuVideoDecoderFactories::AsyncCreateTextures(
- int32 count, const gfx::Size& size, uint32 texture_target) {
+ int32 count, const gfx::Size& size, std::vector<uint32>* texture_ids,
+ uint32 texture_target, bool* success, base::WaitableEvent* waiter) {
DCHECK(message_loop_->BelongsToCurrentThread());
DCHECK(texture_target);
-
if (!context_) {
- async_waiter_.Signal();
+ *success = false;
+ waiter->Signal();
return;
}
gpu::gles2::GLES2Implementation* gles2 = context_->GetImplementation();
- created_textures_.resize(count);
- gles2->GenTextures(count, &created_textures_[0]);
+ texture_ids->resize(count);
+ gles2->GenTextures(count, &texture_ids->at(0));
for (int i = 0; i < count; ++i) {
gles2->ActiveTexture(GL_TEXTURE0);
- uint32 texture_id = created_textures_[i];
+ uint32 texture_id = texture_ids->at(i);
gles2->BindTexture(texture_target, texture_id);
gles2->TexParameteri(texture_target, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
gles2->TexParameteri(texture_target, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
@@ -141,7 +135,8 @@ void RendererGpuVideoDecoderFactories::AsyncCreateTextures(
// reused, this should not be unacceptably expensive.
gles2->Flush();
DCHECK_EQ(gles2->GetError(), static_cast<GLenum>(GL_NO_ERROR));
- async_waiter_.Signal();
+ *success = true;
+ waiter->Signal();
}
void RendererGpuVideoDecoderFactories::DeleteTexture(uint32 texture_id) {
@@ -154,7 +149,6 @@ void RendererGpuVideoDecoderFactories::AsyncDeleteTexture(uint32 texture_id) {
DCHECK(message_loop_->BelongsToCurrentThread());
if (!context_)
return;
-
gpu::gles2::GLES2Implementation* gles2 = context_->GetImplementation();
gles2->DeleteTextures(1, &texture_id);
DCHECK_EQ(gles2->GetError(), static_cast<GLenum>(GL_NO_ERROR));
@@ -162,33 +156,24 @@ void RendererGpuVideoDecoderFactories::AsyncDeleteTexture(uint32 texture_id) {
void RendererGpuVideoDecoderFactories::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
- // until the AsyncReadPixels() call completes.
- read_pixels_bitmap_.setPixelRef(pixels.pixelRef());
-
+ void* pixels) {
+ base::WaitableEvent waiter(false, false);
if (!message_loop_->BelongsToCurrentThread()) {
message_loop_->PostTask(FROM_HERE, base::Bind(
&RendererGpuVideoDecoderFactories::AsyncReadPixels, this,
- texture_id, texture_target, size));
- base::WaitableEvent* objects[] = {&aborted_waiter_, &async_waiter_};
- if (base::WaitableEvent::WaitMany(objects, arraysize(objects)) == 0)
- return;
+ texture_id, texture_target, size, pixels, &waiter));
+ waiter.Wait();
} else {
- AsyncReadPixels(texture_id, texture_target, size);
+ AsyncReadPixels(texture_id, texture_target, size, pixels, &waiter);
}
- read_pixels_bitmap_.setPixelRef(NULL);
}
void RendererGpuVideoDecoderFactories::AsyncReadPixels(
- uint32 texture_id, uint32 texture_target, const gfx::Size& size) {
+ uint32 texture_id, uint32 texture_target, const gfx::Size& size,
+ void* pixels, base::WaitableEvent* waiter) {
DCHECK(message_loop_->BelongsToCurrentThread());
- if (!context_) {
- async_waiter_.Signal();
+ if (!context_)
return;
- }
gpu::gles2::GLES2Implementation* gles2 = context_->GetImplementation();
@@ -209,33 +194,30 @@ void RendererGpuVideoDecoderFactories::AsyncReadPixels(
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());
+ GL_UNSIGNED_BYTE, pixels);
gles2->DeleteFramebuffers(1, &fb);
gles2->DeleteTextures(1, &tmp_texture);
DCHECK_EQ(gles2->GetError(), static_cast<GLenum>(GL_NO_ERROR));
- async_waiter_.Signal();
+ waiter->Signal();
}
base::SharedMemory* RendererGpuVideoDecoderFactories::CreateSharedMemory(
size_t size) {
DCHECK_NE(MessageLoop::current(), ChildThread::current()->message_loop());
+ base::SharedMemory* shm = NULL;
+ base::WaitableEvent waiter(false, false);
ChildThread::current()->message_loop()->PostTask(FROM_HERE, base::Bind(
&RendererGpuVideoDecoderFactories::AsyncCreateSharedMemory, this,
- size));
-
- base::WaitableEvent* objects[] = {&aborted_waiter_, &async_waiter_};
- if (base::WaitableEvent::WaitMany(objects, arraysize(objects)) == 0)
- return NULL;
- return shared_memory_segment_.release();
+ size, &shm, &waiter));
+ waiter.Wait();
+ return shm;
}
void RendererGpuVideoDecoderFactories::AsyncCreateSharedMemory(
- size_t size) {
+ size_t size, base::SharedMemory** shm, base::WaitableEvent* waiter) {
DCHECK_EQ(MessageLoop::current(), ChildThread::current()->message_loop());
-
- shared_memory_segment_.reset(
- ChildThread::current()->AllocateSharedMemory(size));
- async_waiter_.Signal();
+ *shm = ChildThread::current()->AllocateSharedMemory(size);
+ waiter->Signal();
}
scoped_refptr<base::MessageLoopProxy>
@@ -243,18 +225,4 @@ RendererGpuVideoDecoderFactories::GetMessageLoop() {
return message_loop_;
}
-void RendererGpuVideoDecoderFactories::Abort() {
- aborted_waiter_.Signal();
-}
-
-bool RendererGpuVideoDecoderFactories::IsAborted() {
- return aborted_waiter_.IsSignaled();
-}
-
-void RendererGpuVideoDecoderFactories::AsyncDestroyVideoDecodeAccelerator() {
- // OK to release because Destroy() will delete the VDA instance.
- if (vda_)
- vda_.release()->Destroy();
-}
-
} // namespace content