Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(153)

Side by Side Diff: content/common/gpu/client/gpu_jpeg_decode_accelerator_host.cc

Issue 1656433002: Sample code: IPC Transport object for GPU Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: GpuMemoryBufferService + Transport object. TODO: Eliminate ChildThreadImpl dependency Created 4 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright 2015 The Chromium Authors. All rights reserved. 1 // Copyright 2015 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "content/common/gpu/client/gpu_jpeg_decode_accelerator_host.h" 5 #include "content/common/gpu/client/gpu_jpeg_decode_accelerator_host.h"
6 6
7 #include <stddef.h> 7 #include <stddef.h>
8 8
9 #include "base/bind.h" 9 #include "base/bind.h"
10 #include "base/logging.h" 10 #include "base/logging.h"
11 #include "base/macros.h" 11 #include "base/macros.h"
12 #include "base/memory/shared_memory_handle.h" 12 #include "base/memory/shared_memory_handle.h"
13 #include "base/memory/weak_ptr.h" 13 #include "base/memory/weak_ptr.h"
14 #include "base/synchronization/waitable_event.h" 14 #include "base/synchronization/waitable_event.h"
15 #include "build/build_config.h" 15 #include "build/build_config.h"
16 #include "content/common/gpu/client/gpu_channel_host.h" 16 #include "content/common/gpu/client/gpu_channel_host.h"
17 #include "content/common/gpu/gpu_messages.h" 17 #include "content/common/gpu/gpu_messages.h"
18 #include "ipc/ipc_listener.h" 18 #include "content/common/gpu/jpeg_decode_params.h"
19 #include "ipc/ipc_message_macros.h"
20 #include "ipc/ipc_message_utils.h"
21 19
22 namespace content { 20 namespace content {
23 21
24 // Class to receive AcceleratedJpegDecoderHostMsg_DecodeAck IPC message on IO 22 // Class to receive AcceleratedJpegDecoderHostMsg_DecodeAck IPC message on IO
25 // thread. This does very similar what MessageFilter usually does. It is not 23 // thread. This does very similar what MessageFilter usually does. It is not
26 // MessageFilter because GpuChannelHost doesn't support AddFilter. 24 // MessageFilter because GpuChannelHost doesn't support AddFilter.
27 class GpuJpegDecodeAcceleratorHost::Receiver : public IPC::Listener, 25 class GpuJpegDecodeAcceleratorHost::Receiver
28 public base::NonThreadSafe { 26 : public GpuJpegDecodeAcceleratorHostIPCTransport::Client,
27 public base::NonThreadSafe {
29 public: 28 public:
30 Receiver(Client* client, 29 Receiver(media::JpegDecodeAccelerator::Client* client) : client_(client) {
31 const scoped_refptr<base::SingleThreadTaskRunner>& io_task_runner)
32 : client_(client),
33 io_task_runner_(io_task_runner),
34 weak_factory_for_io_(this) {
35 DCHECK(CalledOnValidThread()); 30 DCHECK(CalledOnValidThread());
36 } 31 }
37 32
38 ~Receiver() override { DCHECK(CalledOnValidThread()); } 33 ~Receiver() override { DCHECK(CalledOnValidThread()); }
39 34
40 void InvalidateWeakPtr(base::WaitableEvent* event) {
41 DCHECK(io_task_runner_->BelongsToCurrentThread());
42 weak_factory_for_io_.InvalidateWeakPtrs();
43 event->Signal();
44 }
45
46 // IPC::Listener implementation.
47 void OnChannelError() override {
48 DCHECK(io_task_runner_->BelongsToCurrentThread());
49
50 OnDecodeAck(kInvalidBitstreamBufferId, PLATFORM_FAILURE);
51 }
52
53 bool OnMessageReceived(const IPC::Message& msg) override {
54 DCHECK(io_task_runner_->BelongsToCurrentThread());
55
56 bool handled = true;
57 IPC_BEGIN_MESSAGE_MAP(GpuJpegDecodeAcceleratorHost::Receiver, msg)
58 IPC_MESSAGE_HANDLER(AcceleratedJpegDecoderHostMsg_DecodeAck, OnDecodeAck)
59 IPC_MESSAGE_UNHANDLED(handled = false)
60 IPC_END_MESSAGE_MAP()
61 DCHECK(handled);
62 return handled;
63 }
64
65 base::WeakPtr<IPC::Listener> AsWeakPtrForIO() {
66 return weak_factory_for_io_.GetWeakPtr();
67 }
68
69 private: 35 private:
70 void OnDecodeAck(int32_t bitstream_buffer_id, Error error) { 36 void OnDecodeAck(int32_t bitstream_buffer_id, Error error) override {
71 DCHECK(io_task_runner_->BelongsToCurrentThread()); 37 // TODO(fsamuel): Verify this is called on the IO thread.
72
73 if (!client_) 38 if (!client_)
74 return; 39 return;
75 40
76 if (error == media::JpegDecodeAccelerator::NO_ERRORS) { 41 if (error == media::JpegDecodeAccelerator::NO_ERRORS) {
77 client_->VideoFrameReady(bitstream_buffer_id); 42 client_->VideoFrameReady(bitstream_buffer_id);
78 } else { 43 } else {
79 // Only NotifyError once. 44 // Only NotifyError once.
80 // Client::NotifyError() may trigger deletion of |this| (on another 45 // Client::NotifyError() may trigger deletion of |this| (on another
81 // thread), so calling it needs to be the last thing done on this stack! 46 // thread), so calling it needs to be the last thing done on this stack!
82 media::JpegDecodeAccelerator::Client* client = nullptr; 47 media::JpegDecodeAccelerator::Client* client = nullptr;
83 std::swap(client, client_); 48 std::swap(client, client_);
84 client->NotifyError(bitstream_buffer_id, error); 49 client->NotifyError(bitstream_buffer_id, error);
85 } 50 }
86 } 51 }
87 52
88 Client* client_; 53 media::JpegDecodeAccelerator::Client* client_;
89
90 // GPU IO task runner.
91 scoped_refptr<base::SingleThreadTaskRunner> io_task_runner_;
92
93 // Weak pointers will be invalidated on IO thread.
94 base::WeakPtrFactory<Receiver> weak_factory_for_io_;
95 54
96 DISALLOW_COPY_AND_ASSIGN(Receiver); 55 DISALLOW_COPY_AND_ASSIGN(Receiver);
97 }; 56 };
98 57
99 GpuJpegDecodeAcceleratorHost::GpuJpegDecodeAcceleratorHost( 58 GpuJpegDecodeAcceleratorHost::GpuJpegDecodeAcceleratorHost(
100 GpuChannelHost* channel, 59 GpuChannelHost* channel,
101 int32_t route_id, 60 scoped_ptr<GpuJpegDecodeAcceleratorHostIPCTransport> transport)
102 const scoped_refptr<base::SingleThreadTaskRunner>& io_task_runner) 61 : channel_(channel), transport_(std::move(transport)) {
103 : channel_(channel),
104 decoder_route_id_(route_id),
105 io_task_runner_(io_task_runner) {
106 DCHECK(channel_); 62 DCHECK(channel_);
107 DCHECK_NE(decoder_route_id_, MSG_ROUTING_NONE);
108 } 63 }
109 64
110 GpuJpegDecodeAcceleratorHost::~GpuJpegDecodeAcceleratorHost() { 65 GpuJpegDecodeAcceleratorHost::~GpuJpegDecodeAcceleratorHost() {
111 DCHECK(CalledOnValidThread()); 66 DCHECK(CalledOnValidThread());
112 Send(new AcceleratedJpegDecoderMsg_Destroy(decoder_route_id_)); 67 transport_->Destroy();
113
114 if (receiver_) {
115 channel_->RemoveRoute(decoder_route_id_);
116
117 // Invalidate weak ptr of |receiver_|. After that, no more messages will be
118 // routed to |receiver_| on IO thread.
119 base::WaitableEvent event(false, false);
120 io_task_runner_->PostTask(FROM_HERE,
121 base::Bind(&Receiver::InvalidateWeakPtr,
122 base::Unretained(receiver_.get()),
123 base::Unretained(&event)));
124 event.Wait();
125 }
126 } 68 }
127 69
128 bool GpuJpegDecodeAcceleratorHost::Initialize( 70 bool GpuJpegDecodeAcceleratorHost::Initialize(
129 media::JpegDecodeAccelerator::Client* client) { 71 media::JpegDecodeAccelerator::Client* client) {
130 DCHECK(CalledOnValidThread()); 72 DCHECK(CalledOnValidThread());
131 73
132 bool succeeded = false; 74 receiver_.reset(new Receiver(client));
133 // This cannot be on IO thread because the msg is synchronous. 75 transport_->SetClient(receiver_.get());
134 Send(new GpuMsg_CreateJpegDecoder(decoder_route_id_, &succeeded));
135
136 if (!succeeded) {
137 DLOG(ERROR) << "Send(GpuMsg_CreateJpegDecoder()) failed";
138 return false;
139 }
140
141 receiver_.reset(new Receiver(client, io_task_runner_));
142 76
143 return true; 77 return true;
144 } 78 }
145 79
146 void GpuJpegDecodeAcceleratorHost::Decode( 80 void GpuJpegDecodeAcceleratorHost::Decode(
147 const media::BitstreamBuffer& bitstream_buffer, 81 const media::BitstreamBuffer& bitstream_buffer,
148 const scoped_refptr<media::VideoFrame>& video_frame) { 82 const scoped_refptr<media::VideoFrame>& video_frame) {
149 DCHECK(CalledOnValidThread()); 83 DCHECK(CalledOnValidThread());
150 84
151 DCHECK( 85 DCHECK(
(...skipping 16 matching lines...) Expand all
168 } 102 }
169 #else 103 #else
170 // TODO(kcwu) fix the handle leak after crbug.com/493414 resolved. 104 // TODO(kcwu) fix the handle leak after crbug.com/493414 resolved.
171 #endif 105 #endif
172 return; 106 return;
173 } 107 }
174 108
175 size_t output_buffer_size = media::VideoFrame::AllocationSize( 109 size_t output_buffer_size = media::VideoFrame::AllocationSize(
176 video_frame->format(), video_frame->coded_size()); 110 video_frame->format(), video_frame->coded_size());
177 111
178 AcceleratedJpegDecoderMsg_Decode_Params decode_params; 112 JpegDecodeParams decode_params;
179 decode_params.coded_size = video_frame->coded_size(); 113 decode_params.coded_size = video_frame->coded_size();
180 decode_params.input_buffer_id = bitstream_buffer.id(); 114 decode_params.input_buffer_id = bitstream_buffer.id();
181 decode_params.input_buffer_handle = input_handle; 115 decode_params.input_buffer_handle = input_handle;
182 decode_params.input_buffer_size = bitstream_buffer.size(); 116 decode_params.input_buffer_size = bitstream_buffer.size();
183 decode_params.output_video_frame_handle = output_handle; 117 decode_params.output_video_frame_handle = output_handle;
184 decode_params.output_buffer_size = output_buffer_size; 118 decode_params.output_buffer_size = output_buffer_size;
185 Send(new AcceleratedJpegDecoderMsg_Decode(decoder_route_id_, decode_params)); 119 transport_->Decode(decode_params);
186 } 120 }
187 121
188 bool GpuJpegDecodeAcceleratorHost::IsSupported() { 122 bool GpuJpegDecodeAcceleratorHost::IsSupported() {
189 return channel_->gpu_info().jpeg_decode_accelerator_supported; 123 return channel_->gpu_info().jpeg_decode_accelerator_supported;
190 } 124 }
191 125
192 void GpuJpegDecodeAcceleratorHost::Send(IPC::Message* message) {
193 DCHECK(CalledOnValidThread());
194
195 if (!channel_->Send(message)) {
196 DLOG(ERROR) << "Send(" << message->type() << ") failed";
197 }
198 }
199
200 base::WeakPtr<IPC::Listener> GpuJpegDecodeAcceleratorHost::GetReceiver() {
201 return receiver_->AsWeakPtrForIO();
202 }
203
204 } // namespace content 126 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698