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

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: Fix linux/windows hardware path Created 7 years, 8 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 80 matching lines...) Expand 10 before | Expand all | Expand 10 after
91 vda_.reset(gpu_channel_host_->CreateVideoDecoder( 91 vda_.reset(gpu_channel_host_->CreateVideoDecoder(
92 context_->GetCommandBufferProxy()->GetRouteID(), 92 context_->GetCommandBufferProxy()->GetRouteID(),
93 profile, client)); 93 profile, client));
94 } 94 }
95 async_waiter_.Signal(); 95 async_waiter_.Signal();
96 } 96 }
97 97
98 bool RendererGpuVideoDecoderFactories::CreateTextures( 98 bool RendererGpuVideoDecoderFactories::CreateTextures(
99 int32 count, const gfx::Size& size, 99 int32 count, const gfx::Size& size,
100 std::vector<uint32>* texture_ids, 100 std::vector<uint32>* texture_ids,
101 std::vector<gpu::Mailbox>* texture_mailboxes,
101 uint32 texture_target) { 102 uint32 texture_target) {
102 DCHECK(!message_loop_->BelongsToCurrentThread()); 103 DCHECK(!message_loop_->BelongsToCurrentThread());
103 message_loop_->PostTask(FROM_HERE, base::Bind( 104 message_loop_->PostTask(FROM_HERE, base::Bind(
104 &RendererGpuVideoDecoderFactories::AsyncCreateTextures, this, 105 &RendererGpuVideoDecoderFactories::AsyncCreateTextures, this,
105 count, size, texture_target)); 106 count, size, texture_target));
106 107
107 base::WaitableEvent* objects[] = {&aborted_waiter_, &async_waiter_}; 108 base::WaitableEvent* objects[] = {&aborted_waiter_, &async_waiter_};
108 if (base::WaitableEvent::WaitMany(objects, arraysize(objects)) == 0) 109 if (base::WaitableEvent::WaitMany(objects, arraysize(objects)) == 0)
109 return false; 110 return false;
110 texture_ids->swap(created_textures_); 111 texture_ids->swap(created_textures_);
112 texture_mailboxes->swap(created_texture_mailboxes_);
111 return true; 113 return true;
112 } 114 }
113 115
114 void RendererGpuVideoDecoderFactories::AsyncCreateTextures( 116 void RendererGpuVideoDecoderFactories::AsyncCreateTextures(
115 int32 count, const gfx::Size& size, uint32 texture_target) { 117 int32 count, const gfx::Size& size, uint32 texture_target) {
116 DCHECK(message_loop_->BelongsToCurrentThread()); 118 DCHECK(message_loop_->BelongsToCurrentThread());
117 DCHECK(texture_target); 119 DCHECK(texture_target);
118 120
119 if (!context_) { 121 if (!context_) {
120 async_waiter_.Signal(); 122 async_waiter_.Signal();
121 return; 123 return;
122 } 124 }
123 gpu::gles2::GLES2Implementation* gles2 = context_->GetImplementation(); 125 gpu::gles2::GLES2Implementation* gles2 = context_->GetImplementation();
124 created_textures_.resize(count); 126 created_textures_.resize(count);
127 created_texture_mailboxes_.resize(count);
125 gles2->GenTextures(count, &created_textures_[0]); 128 gles2->GenTextures(count, &created_textures_[0]);
126 for (int i = 0; i < count; ++i) { 129 for (int i = 0; i < count; ++i) {
127 gles2->ActiveTexture(GL_TEXTURE0); 130 gles2->ActiveTexture(GL_TEXTURE0);
128 uint32 texture_id = created_textures_[i]; 131 uint32 texture_id = created_textures_[i];
129 gles2->BindTexture(texture_target, texture_id); 132 gles2->BindTexture(texture_target, texture_id);
130 gles2->TexParameteri(texture_target, GL_TEXTURE_MIN_FILTER, GL_LINEAR); 133 gles2->TexParameteri(texture_target, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
131 gles2->TexParameteri(texture_target, GL_TEXTURE_MAG_FILTER, GL_LINEAR); 134 gles2->TexParameteri(texture_target, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
132 gles2->TexParameteri(texture_target, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); 135 gles2->TexParameteri(texture_target, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
133 gles2->TexParameteri(texture_target, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); 136 gles2->TexParameteri(texture_target, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
134 if (texture_target == GL_TEXTURE_2D) { 137 if (texture_target == GL_TEXTURE_2D) {
135 gles2->TexImage2D(texture_target, 0, GL_RGBA, size.width(), size.height(), 138 gles2->TexImage2D(texture_target, 0, GL_RGBA, size.width(), size.height(),
136 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL); 139 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
137 } 140 }
141 gles2->GenMailboxCHROMIUM(created_texture_mailboxes_[i].name);
138 } 142 }
139 // We need a glFlush here to guarantee the decoder (in the GPU process) can 143 // We need a glFlush here to guarantee the decoder (in the GPU process) can
140 // use the texture ids we return here. Since textures are expected to be 144 // use the texture ids we return here. Since textures are expected to be
141 // reused, this should not be unacceptably expensive. 145 // reused, this should not be unacceptably expensive.
142 gles2->Flush(); 146 gles2->Flush();
143 DCHECK_EQ(gles2->GetError(), static_cast<GLenum>(GL_NO_ERROR)); 147 DCHECK_EQ(gles2->GetError(), static_cast<GLenum>(GL_NO_ERROR));
144 async_waiter_.Signal(); 148 async_waiter_.Signal();
145 } 149 }
146 150
147 void RendererGpuVideoDecoderFactories::DeleteTexture(uint32 texture_id) { 151 void RendererGpuVideoDecoderFactories::DeleteTexture(uint32 texture_id) {
148 DCHECK(!message_loop_->BelongsToCurrentThread()); 152 DCHECK(!message_loop_->BelongsToCurrentThread());
149 message_loop_->PostTask(FROM_HERE, base::Bind( 153 message_loop_->PostTask(FROM_HERE, base::Bind(
150 &RendererGpuVideoDecoderFactories::AsyncDeleteTexture, this, texture_id)); 154 &RendererGpuVideoDecoderFactories::AsyncDeleteTexture, this, texture_id));
151 } 155 }
152 156
153 void RendererGpuVideoDecoderFactories::AsyncDeleteTexture(uint32 texture_id) { 157 void RendererGpuVideoDecoderFactories::AsyncDeleteTexture(uint32 texture_id) {
154 DCHECK(message_loop_->BelongsToCurrentThread()); 158 DCHECK(message_loop_->BelongsToCurrentThread());
155 if (!context_) 159 if (!context_)
156 return; 160 return;
157 161
158 gpu::gles2::GLES2Implementation* gles2 = context_->GetImplementation(); 162 gpu::gles2::GLES2Implementation* gles2 = context_->GetImplementation();
159 gles2->DeleteTextures(1, &texture_id); 163 gles2->DeleteTextures(1, &texture_id);
160 DCHECK_EQ(gles2->GetError(), static_cast<GLenum>(GL_NO_ERROR)); 164 DCHECK_EQ(gles2->GetError(), static_cast<GLenum>(GL_NO_ERROR));
161 } 165 }
162 166
167 uint32 RendererGpuVideoDecoderFactories::ProduceTextureToMailbox(
168 const gpu::Mailbox& mailbox,
169 uint32 texture_id,
170 uint32 texture_target) {
171 uint32 sync_point = 0;
172 if (message_loop_->BelongsToCurrentThread()) {
173 AsyncProduceTextureToMailbox(
174 mailbox, texture_id, texture_target, &sync_point);
175 return sync_point;
176 }
177
178 message_loop_->PostTask(FROM_HERE, base::Bind(
179 &RendererGpuVideoDecoderFactories::AsyncProduceTextureToMailbox,
180 this,
181 mailbox,
182 texture_id,
183 texture_target,
184 &sync_point));
185 base::WaitableEvent* objects[] = {&aborted_waiter_, &async_waiter_};
186 base::WaitableEvent::WaitMany(objects, arraysize(objects));
187 return sync_point;
188 }
189
190 void RendererGpuVideoDecoderFactories::AsyncProduceTextureToMailbox(
191 const gpu::Mailbox& mailbox,
192 uint32 texture_id,
193 uint32 texture_target,
194 uint32* sync_point) {
195 DCHECK(message_loop_->BelongsToCurrentThread());
196
197 *sync_point = 0;
198 if (!context_) {
199 async_waiter_.Signal();
200 return;
201 }
202
203 gpu::gles2::GLES2Implementation* gles2 = context_->GetImplementation();
204 gles2->BindTexture(texture_target, texture_id);
205 gles2->ProduceTextureCHROMIUM(texture_target, mailbox.name);
206 *sync_point = gles2->InsertSyncPointCHROMIUM();
207 async_waiter_.Signal();
danakj 2013/04/19 20:44:43 I was missing these Signal()s which broke everythi
208 }
209
210 void RendererGpuVideoDecoderFactories::ConsumeMailboxToTexture(
211 const gpu::Mailbox& mailbox,
212 uint32 texture_id,
213 uint32 texture_target,
214 uint32 sync_point) {
215 if (message_loop_->BelongsToCurrentThread()) {
216 AsyncConsumeMailboxToTexture(
217 mailbox, texture_id, texture_target, sync_point);
218 return;
219 }
220
221 message_loop_->PostTask(FROM_HERE, base::Bind(
222 &RendererGpuVideoDecoderFactories::AsyncConsumeMailboxToTexture,
223 this,
224 mailbox,
225 texture_id,
226 texture_target,
227 sync_point));
228 base::WaitableEvent* objects[] = {&aborted_waiter_, &async_waiter_};
229 base::WaitableEvent::WaitMany(objects, arraysize(objects));
230 }
231
232 void RendererGpuVideoDecoderFactories::AsyncConsumeMailboxToTexture(
233 const gpu::Mailbox& mailbox,
234 uint32 texture_id,
235 uint32 texture_target,
236 uint32 sync_point) {
237 DCHECK(message_loop_->BelongsToCurrentThread());
238 if (!context_) {
239 async_waiter_.Signal();
240 return;
241 }
242
243 gpu::gles2::GLES2Implementation* gles2 = context_->GetImplementation();
244 gles2->WaitSyncPointCHROMIUM(sync_point);
245 gles2->BindTexture(texture_target, texture_id);
246 gles2->ConsumeTextureCHROMIUM(texture_target, mailbox.name);
247 async_waiter_.Signal();
248 }
249
163 void RendererGpuVideoDecoderFactories::ReadPixels( 250 void RendererGpuVideoDecoderFactories::ReadPixels(
164 uint32 texture_id, uint32 texture_target, const gfx::Size& size, 251 uint32 texture_id, uint32 texture_target, const gfx::Size& size,
165 const SkBitmap& pixels) { 252 const SkBitmap& pixels) {
166 // SkBitmaps use the SkPixelRef object to refcount the underlying pixels. 253 // SkBitmaps use the SkPixelRef object to refcount the underlying pixels.
167 // Multiple SkBitmaps can share a SkPixelRef instance. We use this to 254 // Multiple SkBitmaps can share a SkPixelRef instance. We use this to
168 // ensure that the underlying pixels in the SkBitmap passed in remain valid 255 // ensure that the underlying pixels in the SkBitmap passed in remain valid
169 // until the AsyncReadPixels() call completes. 256 // until the AsyncReadPixels() call completes.
170 read_pixels_bitmap_.setPixelRef(pixels.pixelRef()); 257 read_pixels_bitmap_.setPixelRef(pixels.pixelRef());
171 258
172 if (!message_loop_->BelongsToCurrentThread()) { 259 if (!message_loop_->BelongsToCurrentThread()) {
(...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after
251 return aborted_waiter_.IsSignaled(); 338 return aborted_waiter_.IsSignaled();
252 } 339 }
253 340
254 void RendererGpuVideoDecoderFactories::AsyncDestroyVideoDecodeAccelerator() { 341 void RendererGpuVideoDecoderFactories::AsyncDestroyVideoDecodeAccelerator() {
255 // OK to release because Destroy() will delete the VDA instance. 342 // OK to release because Destroy() will delete the VDA instance.
256 if (vda_) 343 if (vda_)
257 vda_.release()->Destroy(); 344 vda_.release()->Destroy();
258 } 345 }
259 346
260 } // namespace content 347 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698