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

Side by Side Diff: content/renderer/media/renderer_gpu_video_decoder_factories.cc

Issue 14199002: Send hardware video frames with mailboxes. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: video-mailbox: rebase Created 7 years, 6 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 | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 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/renderer/media/renderer_gpu_video_decoder_factories.h" 5 #include "content/renderer/media/renderer_gpu_video_decoder_factories.h"
6 6
7 #include <GLES2/gl2.h> 7 #include <GLES2/gl2.h>
8 #include <GLES2/gl2ext.h> 8 #include <GLES2/gl2ext.h>
9 9
10 #include "base/bind.h" 10 #include "base/bind.h"
(...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after
92 if (context_.get() && context_->GetCommandBufferProxy()) { 92 if (context_.get() && context_->GetCommandBufferProxy()) {
93 vda_ = gpu_channel_host_->CreateVideoDecoder( 93 vda_ = gpu_channel_host_->CreateVideoDecoder(
94 context_->GetCommandBufferProxy()->GetRouteID(), profile, client); 94 context_->GetCommandBufferProxy()->GetRouteID(), profile, client);
95 } 95 }
96 compositor_loop_async_waiter_.Signal(); 96 compositor_loop_async_waiter_.Signal();
97 } 97 }
98 98
99 bool RendererGpuVideoDecoderFactories::CreateTextures( 99 bool RendererGpuVideoDecoderFactories::CreateTextures(
100 int32 count, const gfx::Size& size, 100 int32 count, const gfx::Size& size,
101 std::vector<uint32>* texture_ids, 101 std::vector<uint32>* texture_ids,
102 std::vector<gpu::Mailbox>* texture_mailboxes,
102 uint32 texture_target) { 103 uint32 texture_target) {
103 DCHECK(!message_loop_->BelongsToCurrentThread()); 104 DCHECK(!message_loop_->BelongsToCurrentThread());
104 message_loop_->PostTask(FROM_HERE, base::Bind( 105 message_loop_->PostTask(FROM_HERE, base::Bind(
105 &RendererGpuVideoDecoderFactories::AsyncCreateTextures, this, 106 &RendererGpuVideoDecoderFactories::AsyncCreateTextures, this,
106 count, size, texture_target)); 107 count, size, texture_target));
107 108
108 base::WaitableEvent* objects[] = {&aborted_waiter_, 109 base::WaitableEvent* objects[] = {&aborted_waiter_,
109 &compositor_loop_async_waiter_}; 110 &compositor_loop_async_waiter_};
110 if (base::WaitableEvent::WaitMany(objects, arraysize(objects)) == 0) 111 if (base::WaitableEvent::WaitMany(objects, arraysize(objects)) == 0)
111 return false; 112 return false;
112 texture_ids->swap(created_textures_); 113 texture_ids->swap(created_textures_);
114 texture_mailboxes->swap(created_texture_mailboxes_);
113 return true; 115 return true;
114 } 116 }
115 117
116 void RendererGpuVideoDecoderFactories::AsyncCreateTextures( 118 void RendererGpuVideoDecoderFactories::AsyncCreateTextures(
117 int32 count, const gfx::Size& size, uint32 texture_target) { 119 int32 count, const gfx::Size& size, uint32 texture_target) {
118 DCHECK(message_loop_->BelongsToCurrentThread()); 120 DCHECK(message_loop_->BelongsToCurrentThread());
119 DCHECK(texture_target); 121 DCHECK(texture_target);
120 122
121 if (!context_.get()) { 123 if (!context_.get()) {
122 compositor_loop_async_waiter_.Signal(); 124 compositor_loop_async_waiter_.Signal();
123 return; 125 return;
124 } 126 }
125 gpu::gles2::GLES2Implementation* gles2 = context_->GetImplementation(); 127 gpu::gles2::GLES2Implementation* gles2 = context_->GetImplementation();
126 created_textures_.resize(count); 128 created_textures_.resize(count);
129 created_texture_mailboxes_.resize(count);
127 gles2->GenTextures(count, &created_textures_[0]); 130 gles2->GenTextures(count, &created_textures_[0]);
128 for (int i = 0; i < count; ++i) { 131 for (int i = 0; i < count; ++i) {
129 gles2->ActiveTexture(GL_TEXTURE0); 132 gles2->ActiveTexture(GL_TEXTURE0);
130 uint32 texture_id = created_textures_[i]; 133 uint32 texture_id = created_textures_[i];
131 gles2->BindTexture(texture_target, texture_id); 134 gles2->BindTexture(texture_target, texture_id);
132 gles2->TexParameteri(texture_target, GL_TEXTURE_MIN_FILTER, GL_LINEAR); 135 gles2->TexParameteri(texture_target, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
133 gles2->TexParameteri(texture_target, GL_TEXTURE_MAG_FILTER, GL_LINEAR); 136 gles2->TexParameteri(texture_target, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
134 gles2->TexParameteri(texture_target, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); 137 gles2->TexParameteri(texture_target, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
135 gles2->TexParameteri(texture_target, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); 138 gles2->TexParameteri(texture_target, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
136 if (texture_target == GL_TEXTURE_2D) { 139 if (texture_target == GL_TEXTURE_2D) {
137 gles2->TexImage2D(texture_target, 0, GL_RGBA, size.width(), size.height(), 140 gles2->TexImage2D(texture_target, 0, GL_RGBA, size.width(), size.height(),
138 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL); 141 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
139 } 142 }
143 gles2->GenMailboxCHROMIUM(created_texture_mailboxes_[i].name);
piman 2013/06/14 21:47:29 With the new semantics, we can simply produce now,
danakj 2013/06/14 21:54:39 Done. Changed produce method to take a set of mail
140 } 144 }
141 // We need a glFlush here to guarantee the decoder (in the GPU process) can 145 // We need a glFlush here to guarantee the decoder (in the GPU process) can
142 // use the texture ids we return here. Since textures are expected to be 146 // use the texture ids we return here. Since textures are expected to be
143 // reused, this should not be unacceptably expensive. 147 // reused, this should not be unacceptably expensive.
144 gles2->Flush(); 148 gles2->Flush();
145 DCHECK_EQ(gles2->GetError(), static_cast<GLenum>(GL_NO_ERROR)); 149 DCHECK_EQ(gles2->GetError(), static_cast<GLenum>(GL_NO_ERROR));
146 compositor_loop_async_waiter_.Signal(); 150 compositor_loop_async_waiter_.Signal();
147 } 151 }
148 152
149 void RendererGpuVideoDecoderFactories::DeleteTexture(uint32 texture_id) { 153 void RendererGpuVideoDecoderFactories::DeleteTexture(uint32 texture_id) {
150 DCHECK(!message_loop_->BelongsToCurrentThread()); 154 DCHECK(!message_loop_->BelongsToCurrentThread());
151 message_loop_->PostTask(FROM_HERE, base::Bind( 155 message_loop_->PostTask(FROM_HERE, base::Bind(
152 &RendererGpuVideoDecoderFactories::AsyncDeleteTexture, this, texture_id)); 156 &RendererGpuVideoDecoderFactories::AsyncDeleteTexture, this, texture_id));
153 } 157 }
154 158
155 void RendererGpuVideoDecoderFactories::AsyncDeleteTexture(uint32 texture_id) { 159 void RendererGpuVideoDecoderFactories::AsyncDeleteTexture(uint32 texture_id) {
156 DCHECK(message_loop_->BelongsToCurrentThread()); 160 DCHECK(message_loop_->BelongsToCurrentThread());
157 if (!context_.get()) 161 if (!context_.get())
158 return; 162 return;
159 163
160 gpu::gles2::GLES2Implementation* gles2 = context_->GetImplementation(); 164 gpu::gles2::GLES2Implementation* gles2 = context_->GetImplementation();
161 gles2->DeleteTextures(1, &texture_id); 165 gles2->DeleteTextures(1, &texture_id);
162 DCHECK_EQ(gles2->GetError(), static_cast<GLenum>(GL_NO_ERROR)); 166 DCHECK_EQ(gles2->GetError(), static_cast<GLenum>(GL_NO_ERROR));
163 } 167 }
164 168
169 uint32 RendererGpuVideoDecoderFactories::ProduceTextureToMailbox(
170 const gpu::Mailbox& mailbox,
171 uint32 texture_id,
172 uint32 texture_target) {
173 uint32 sync_point = 0;
174 if (message_loop_->BelongsToCurrentThread()) {
175 AsyncProduceTextureToMailbox(
176 mailbox, texture_id, texture_target, &sync_point);
177 return sync_point;
178 }
179
180 message_loop_->PostTask(FROM_HERE, base::Bind(
181 &RendererGpuVideoDecoderFactories::AsyncProduceTextureToMailbox,
182 this,
183 mailbox,
184 texture_id,
185 texture_target,
186 &sync_point));
187 base::WaitableEvent* objects[] = {&aborted_waiter_,
188 &compositor_loop_async_waiter_};
189 base::WaitableEvent::WaitMany(objects, arraysize(objects));
190 return sync_point;
191 }
192
193 void RendererGpuVideoDecoderFactories::AsyncProduceTextureToMailbox(
194 const gpu::Mailbox& mailbox,
195 uint32 texture_id,
196 uint32 texture_target,
197 uint32* sync_point) {
198 DCHECK(message_loop_->BelongsToCurrentThread());
199
200 *sync_point = 0;
201 if (!context_) {
202 compositor_loop_async_waiter_.Signal();
203 return;
204 }
205
206 gpu::gles2::GLES2Implementation* gles2 = context_->GetImplementation();
207 gles2->BindTexture(texture_target, texture_id);
208 gles2->ProduceTextureCHROMIUM(texture_target, mailbox.name);
209 *sync_point = gles2->InsertSyncPointCHROMIUM();
210 compositor_loop_async_waiter_.Signal();
211 }
212
213 void RendererGpuVideoDecoderFactories::ConsumeMailboxToTexture(
214 const gpu::Mailbox& mailbox,
215 uint32 texture_id,
216 uint32 texture_target,
217 uint32 sync_point) {
218 if (message_loop_->BelongsToCurrentThread()) {
219 AsyncConsumeMailboxToTexture(
220 mailbox, texture_id, texture_target, sync_point);
221 return;
222 }
223
224 message_loop_->PostTask(FROM_HERE, base::Bind(
225 &RendererGpuVideoDecoderFactories::AsyncConsumeMailboxToTexture,
226 this,
227 mailbox,
228 texture_id,
229 texture_target,
230 sync_point));
231 base::WaitableEvent* objects[] = {&aborted_waiter_,
232 &compositor_loop_async_waiter_};
233 base::WaitableEvent::WaitMany(objects, arraysize(objects));
234 }
235
236 void RendererGpuVideoDecoderFactories::AsyncConsumeMailboxToTexture(
237 const gpu::Mailbox& mailbox,
238 uint32 texture_id,
239 uint32 texture_target,
240 uint32 sync_point) {
241 DCHECK(message_loop_->BelongsToCurrentThread());
242 if (!context_) {
243 compositor_loop_async_waiter_.Signal();
244 return;
245 }
246
247 gpu::gles2::GLES2Implementation* gles2 = context_->GetImplementation();
248 gles2->WaitSyncPointCHROMIUM(sync_point);
249 gles2->BindTexture(texture_target, texture_id);
250 gles2->ConsumeTextureCHROMIUM(texture_target, mailbox.name);
piman 2013/06/14 21:47:29 Same here, we don't actually need to consume any m
danakj 2013/06/14 21:54:39 Done. Changed this method to WaitSyncPoint()
251 compositor_loop_async_waiter_.Signal();
252 }
253
165 void RendererGpuVideoDecoderFactories::ReadPixels( 254 void RendererGpuVideoDecoderFactories::ReadPixels(
166 uint32 texture_id, uint32 texture_target, const gfx::Size& size, 255 uint32 texture_id, uint32 texture_target, const gfx::Size& size,
167 const SkBitmap& pixels) { 256 const SkBitmap& pixels) {
168 // SkBitmaps use the SkPixelRef object to refcount the underlying pixels. 257 // SkBitmaps use the SkPixelRef object to refcount the underlying pixels.
169 // Multiple SkBitmaps can share a SkPixelRef instance. We use this to 258 // Multiple SkBitmaps can share a SkPixelRef instance. We use this to
170 // ensure that the underlying pixels in the SkBitmap passed in remain valid 259 // ensure that the underlying pixels in the SkBitmap passed in remain valid
171 // until the AsyncReadPixels() call completes. 260 // until the AsyncReadPixels() call completes.
172 read_pixels_bitmap_.setPixelRef(pixels.pixelRef()); 261 read_pixels_bitmap_.setPixelRef(pixels.pixelRef());
173 262
174 if (!message_loop_->BelongsToCurrentThread()) { 263 if (!message_loop_->BelongsToCurrentThread()) {
(...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after
256 return aborted_waiter_.IsSignaled(); 345 return aborted_waiter_.IsSignaled();
257 } 346 }
258 347
259 void RendererGpuVideoDecoderFactories::AsyncDestroyVideoDecodeAccelerator() { 348 void RendererGpuVideoDecoderFactories::AsyncDestroyVideoDecodeAccelerator() {
260 // OK to release because Destroy() will delete the VDA instance. 349 // OK to release because Destroy() will delete the VDA instance.
261 if (vda_) 350 if (vda_)
262 vda_.release()->Destroy(); 351 vda_.release()->Destroy();
263 } 352 }
264 353
265 } // namespace content 354 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698