| Index: content/common/gpu/client/ipc/chrome/chrome_gpu_jpeg_decode_accelerator_host_ipc_transport.cc
|
| diff --git a/content/common/gpu/client/ipc/chrome/chrome_gpu_jpeg_decode_accelerator_host_ipc_transport.cc b/content/common/gpu/client/ipc/chrome/chrome_gpu_jpeg_decode_accelerator_host_ipc_transport.cc
|
| new file mode 100644
|
| index 0000000000000000000000000000000000000000..77554d9f982e5290fa0f56898038eaed0764fb7e
|
| --- /dev/null
|
| +++ b/content/common/gpu/client/ipc/chrome/chrome_gpu_jpeg_decode_accelerator_host_ipc_transport.cc
|
| @@ -0,0 +1,179 @@
|
| +// Copyright 2016 The Chromium Authors. All rights reserved.
|
| +// Use of this source code is governed by a BSD-style license that can be
|
| +// found in the LICENSE file.
|
| +
|
| +#include "content/common/gpu/client/ipc/chrome/chrome_gpu_jpeg_decode_accelerator_host_ipc_transport.h"
|
| +
|
| +#include "base/single_thread_task_runner.h"
|
| +#include "content/common/gpu/client/gpu_channel_host_factory.h"
|
| +#include "content/common/gpu/client/ipc/chrome/chrome_gpu_channel_host_ipc_transport.h"
|
| +#include "content/common/gpu/gpu_messages.h"
|
| +#include "ipc/ipc_message.h"
|
| +#include "media/video/jpeg_decode_accelerator.h"
|
| +
|
| +namespace content {
|
| +
|
| +// Class to receive AcceleratedJpegDecoderHostMsg_DecodeAck IPC message on IO
|
| +// thread. This does very similar what MessageFilter usually does. It is not
|
| +// MessageFilter because GpuChannelHost doesn't support AddFilter.
|
| +class ChromeGpuJpegDecodeAcceleratorHostIPCTransport::Receiver
|
| + : public IPC::Listener,
|
| + public base::NonThreadSafe {
|
| + public:
|
| + Receiver(const scoped_refptr<base::SingleThreadTaskRunner>& io_task_runner)
|
| + : client_(nullptr),
|
| + io_task_runner_(io_task_runner),
|
| + weak_factory_for_io_(this) {
|
| + DCHECK(CalledOnValidThread());
|
| + }
|
| +
|
| + ~Receiver() override {
|
| + DCHECK(CalledOnValidThread());
|
| + // Invalidate weak ptr of |receiver_|. After that, no more messages will
|
| + // be routed to |receiver_| on IO thread.
|
| + base::WaitableEvent event(false, false);
|
| + io_task_runner_->PostTask(
|
| + FROM_HERE,
|
| + base::Bind(&Receiver::InvalidateWeakPtr, base::Unretained(this),
|
| + base::Unretained(&event)));
|
| + event.Wait();
|
| + }
|
| +
|
| + void SetClient(GpuJpegDecodeAcceleratorHostIPCTransport::Client* client) {
|
| + base::AutoLock client_lock(client_lock_);
|
| + client_ = client;
|
| + }
|
| +
|
| + void InvalidateWeakPtr(base::WaitableEvent* event) {
|
| + DCHECK(io_task_runner_->BelongsToCurrentThread());
|
| + weak_factory_for_io_.InvalidateWeakPtrs();
|
| + event->Signal();
|
| + }
|
| +
|
| + // IPC::Listener implementation.
|
| + void OnChannelError() override {
|
| + DCHECK(io_task_runner_->BelongsToCurrentThread());
|
| +
|
| + OnDecodeAck(media::JpegDecodeAccelerator::kInvalidBitstreamBufferId,
|
| + media::JpegDecodeAccelerator::PLATFORM_FAILURE);
|
| + }
|
| +
|
| + bool OnMessageReceived(const IPC::Message& msg) override {
|
| + DCHECK(io_task_runner_->BelongsToCurrentThread());
|
| +
|
| + bool handled = true;
|
| + IPC_BEGIN_MESSAGE_MAP(
|
| + ChromeGpuJpegDecodeAcceleratorHostIPCTransport::Receiver, msg)
|
| + IPC_MESSAGE_HANDLER(AcceleratedJpegDecoderHostMsg_DecodeAck, OnDecodeAck)
|
| + IPC_MESSAGE_UNHANDLED(handled = false)
|
| + IPC_END_MESSAGE_MAP()
|
| + DCHECK(handled);
|
| + return handled;
|
| + }
|
| +
|
| + base::WeakPtr<IPC::Listener> AsWeakPtrForIO() {
|
| + return weak_factory_for_io_.GetWeakPtr();
|
| + }
|
| +
|
| + private:
|
| + void OnDecodeAck(int32_t bitstream_buffer_id,
|
| + media::JpegDecodeAccelerator::Error error) {
|
| + DCHECK(io_task_runner_->BelongsToCurrentThread());
|
| + base::AutoLock client_lock(client_lock_);
|
| + if (client_)
|
| + client_->OnDecodeAck(bitstream_buffer_id, error);
|
| + }
|
| +
|
| + base::Lock client_lock_;
|
| + GpuJpegDecodeAcceleratorHostIPCTransport::Client* client_;
|
| +
|
| + // GPU IO task runner.
|
| + scoped_refptr<base::SingleThreadTaskRunner> io_task_runner_;
|
| +
|
| + // Weak pointers will be invalidated on IO thread.
|
| + base::WeakPtrFactory<Receiver> weak_factory_for_io_;
|
| +
|
| + DISALLOW_COPY_AND_ASSIGN(Receiver);
|
| +};
|
| +// static
|
| +scoped_ptr<GpuJpegDecodeAcceleratorHostIPCTransport>
|
| +ChromeGpuJpegDecodeAcceleratorHostIPCTransport::Create() {
|
| + return make_scoped_ptr<GpuJpegDecodeAcceleratorHostIPCTransport>(
|
| + new ChromeGpuJpegDecodeAcceleratorHostIPCTransport());
|
| +}
|
| +
|
| +ChromeGpuJpegDecodeAcceleratorHostIPCTransport::
|
| + ~ChromeGpuJpegDecodeAcceleratorHostIPCTransport() {
|
| + if (channel_transport_ && route_id_ != MSG_ROUTING_NONE) {
|
| + channel_transport_->RemoveRoute(route_id_);
|
| + // This will block until weak pointers are invalidated.
|
| + receiver_.reset();
|
| + }
|
| +}
|
| +
|
| +void ChromeGpuJpegDecodeAcceleratorHostIPCTransport::BindToService(
|
| + ChromeGpuChannelHostIPCTransport* channel_transport) {
|
| + channel_transport_ = channel_transport;
|
| + if (channel_transport_) {
|
| + route_id_ = channel_transport_->GenerateRouteID();
|
| + scoped_refptr<base::SingleThreadTaskRunner> io_task_runner =
|
| + channel_transport_->factory()->GetIOThreadTaskRunner();
|
| + receiver_.reset(new Receiver(io_task_runner));
|
| + if (client_)
|
| + receiver_->SetClient(client_);
|
| + } else {
|
| + route_id_ = MSG_ROUTING_NONE;
|
| + receiver_.reset();
|
| + }
|
| +}
|
| +
|
| +base::WeakPtr<IPC::Listener>
|
| +ChromeGpuJpegDecodeAcceleratorHostIPCTransport::GetWeakPtrForIO() {
|
| + return receiver_->AsWeakPtrForIO();
|
| +}
|
| +
|
| +ChromeGpuJpegDecodeAcceleratorHostIPCTransport::
|
| + ChromeGpuJpegDecodeAcceleratorHostIPCTransport()
|
| + : channel_transport_(nullptr),
|
| + route_id_(MSG_ROUTING_NONE),
|
| + client_(nullptr) {}
|
| +
|
| +bool ChromeGpuJpegDecodeAcceleratorHostIPCTransport::Send(
|
| + IPC::Message* message) {
|
| + if (channel_transport_) {
|
| + if (channel_transport_->Send(message)) {
|
| + return true;
|
| + } else {
|
| + uint32_t message_type = message->type();
|
| + DLOG(ERROR) << "Send(" << message_type << ") failed";
|
| + return false;
|
| + }
|
| + }
|
| + // Callee takes ownership of message, regardless of whether Send is
|
| + // successful. See IPC::Sender.
|
| + delete message;
|
| + return false;
|
| +}
|
| +
|
| +bool ChromeGpuJpegDecodeAcceleratorHostIPCTransport::CreateJpegDecoder(
|
| + bool* succeeded) {
|
| + return Send(new GpuMsg_CreateJpegDecoder(route_id_, succeeded));
|
| +}
|
| +
|
| +bool ChromeGpuJpegDecodeAcceleratorHostIPCTransport::Decode(
|
| + const JpegDecodeParams& params) {
|
| + return Send(new AcceleratedJpegDecoderMsg_Decode(route_id_, params));
|
| +}
|
| +
|
| +bool ChromeGpuJpegDecodeAcceleratorHostIPCTransport::Destroy() {
|
| + return Send(new AcceleratedJpegDecoderMsg_Destroy(route_id_));
|
| +}
|
| +
|
| +void ChromeGpuJpegDecodeAcceleratorHostIPCTransport::SetClient(
|
| + GpuJpegDecodeAcceleratorHostIPCTransport::Client* client) {
|
| + client_ = client;
|
| + if (receiver_)
|
| + receiver_->SetClient(client);
|
| +}
|
| +
|
| +} // namespace content
|
|
|