OLD | NEW |
1 // Copyright (c) 2014 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2014 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 <GLES2/gl2.h> | 5 #include <GLES2/gl2.h> |
6 #include <GLES2/gl2ext.h> | 6 #include <GLES2/gl2ext.h> |
7 #include <stdio.h> | 7 #include <stdio.h> |
8 #include <string.h> | 8 #include <string.h> |
9 | 9 |
10 #include <iostream> | 10 #include <iostream> |
(...skipping 11 matching lines...) Expand all Loading... |
22 #include "ppapi/cpp/rect.h" | 22 #include "ppapi/cpp/rect.h" |
23 #include "ppapi/cpp/var.h" | 23 #include "ppapi/cpp/var.h" |
24 #include "ppapi/cpp/video_decoder.h" | 24 #include "ppapi/cpp/video_decoder.h" |
25 #include "ppapi/utility/completion_callback_factory.h" | 25 #include "ppapi/utility/completion_callback_factory.h" |
26 | 26 |
27 // VP8 is more likely to work on different versions of Chrome. Undefine this | 27 // VP8 is more likely to work on different versions of Chrome. Undefine this |
28 // to decode H264. | 28 // to decode H264. |
29 #define USE_VP8_TESTDATA_INSTEAD_OF_H264 | 29 #define USE_VP8_TESTDATA_INSTEAD_OF_H264 |
30 #include "testdata.h" | 30 #include "testdata.h" |
31 | 31 |
32 | |
33 // Use assert as a poor-man's CHECK, even in non-debug mode. | 32 // Use assert as a poor-man's CHECK, even in non-debug mode. |
34 // Since <assert.h> redefines assert on every inclusion (it doesn't use | 33 // Since <assert.h> redefines assert on every inclusion (it doesn't use |
35 // include-guards), make sure this is the last file #include'd in this file. | 34 // include-guards), make sure this is the last file #include'd in this file. |
36 #undef NDEBUG | 35 #undef NDEBUG |
37 #include <assert.h> | 36 #include <assert.h> |
38 | 37 |
39 // Assert |context_| isn't holding any GL Errors. Done as a macro instead of a | 38 // Assert |context_| isn't holding any GL Errors. Done as a macro instead of a |
40 // function to preserve line number information in the failure message. | 39 // function to preserve line number information in the failure message. |
41 #define assertNoGLError() assert(!gles2_if_->GetError(context_->pp_resource())); | 40 #define assertNoGLError() assert(!gles2_if_->GetError(context_->pp_resource())); |
42 | 41 |
(...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
106 std::ostringstream stream_; | 105 std::ostringstream stream_; |
107 }; | 106 }; |
108 | 107 |
109 void InitializeDecoders(); | 108 void InitializeDecoders(); |
110 | 109 |
111 // GL-related functions. | 110 // GL-related functions. |
112 void InitGL(); | 111 void InitGL(); |
113 void CreateGLObjects(); | 112 void CreateGLObjects(); |
114 void Create2DProgramOnce(); | 113 void Create2DProgramOnce(); |
115 void CreateRectangleARBProgramOnce(); | 114 void CreateRectangleARBProgramOnce(); |
| 115 void CreateExternalOESProgramOnce(); |
116 Shader CreateProgram(const char* vertex_shader, const char* fragment_shader); | 116 Shader CreateProgram(const char* vertex_shader, const char* fragment_shader); |
117 void CreateShader(GLuint program, GLenum type, const char* source, int size); | 117 void CreateShader(GLuint program, GLenum type, const char* source, int size); |
118 void PaintNextPicture(); | 118 void PaintNextPicture(); |
119 void PaintFinished(int32_t result); | 119 void PaintFinished(int32_t result); |
120 | 120 |
121 pp::Size plugin_size_; | 121 pp::Size plugin_size_; |
122 bool is_painting_; | 122 bool is_painting_; |
123 // When decode outpaces render, we queue up decoded pictures for later | 123 // When decode outpaces render, we queue up decoded pictures for later |
124 // painting. | 124 // painting. |
125 typedef std::queue<PendingPicture> PendingPictureQueue; | 125 typedef std::queue<PendingPicture> PendingPictureQueue; |
(...skipping 12 matching lines...) Expand all Loading... |
138 | 138 |
139 // Owned data. | 139 // Owned data. |
140 pp::Graphics3D* context_; | 140 pp::Graphics3D* context_; |
141 typedef std::vector<Decoder*> DecoderList; | 141 typedef std::vector<Decoder*> DecoderList; |
142 DecoderList video_decoders_; | 142 DecoderList video_decoders_; |
143 | 143 |
144 // Shader program to draw GL_TEXTURE_2D target. | 144 // Shader program to draw GL_TEXTURE_2D target. |
145 Shader shader_2d_; | 145 Shader shader_2d_; |
146 // Shader program to draw GL_TEXTURE_RECTANGLE_ARB target. | 146 // Shader program to draw GL_TEXTURE_RECTANGLE_ARB target. |
147 Shader shader_rectangle_arb_; | 147 Shader shader_rectangle_arb_; |
| 148 // Shader program to draw GL_TEXTURE_EXTERNAL_OES target. |
| 149 Shader shader_external_oes_; |
148 }; | 150 }; |
149 | 151 |
150 class Decoder { | 152 class Decoder { |
151 public: | 153 public: |
152 Decoder(MyInstance* instance, int id, const pp::Graphics3D& graphics_3d); | 154 Decoder(MyInstance* instance, int id, const pp::Graphics3D& graphics_3d); |
153 ~Decoder(); | 155 ~Decoder(); |
154 | 156 |
155 int id() const { return id_; } | 157 int id() const { return id_; } |
156 bool flushing() const { return flushing_; } | 158 bool flushing() const { return flushing_; } |
157 bool resetting() const { return resetting_; } | 159 bool resetting() const { return resetting_; } |
158 | 160 |
159 void Reset(); | 161 void Reset(); |
160 void RecyclePicture(const PP_VideoPicture& picture); | 162 void RecyclePicture(const PP_VideoPicture& picture); |
161 | 163 |
| 164 PP_TimeTicks GetAverageLatency() { |
| 165 return num_pictures_ ? total_latency_ / num_pictures_ : 0; |
| 166 } |
| 167 |
162 private: | 168 private: |
163 void InitializeDone(int32_t result); | 169 void InitializeDone(int32_t result); |
164 void Start(); | 170 void Start(); |
165 void DecodeNextFrame(); | 171 void DecodeNextFrame(); |
166 void DecodeDone(int32_t result); | 172 void DecodeDone(int32_t result); |
167 void PictureReady(int32_t result, PP_VideoPicture picture); | 173 void PictureReady(int32_t result, PP_VideoPicture picture); |
168 void FlushDone(int32_t result); | 174 void FlushDone(int32_t result); |
169 void ResetDone(int32_t result); | 175 void ResetDone(int32_t result); |
170 | 176 |
171 MyInstance* instance_; | 177 MyInstance* instance_; |
172 int id_; | 178 int id_; |
173 | 179 |
174 pp::VideoDecoder* decoder_; | 180 pp::VideoDecoder* decoder_; |
175 pp::CompletionCallbackFactory<Decoder> callback_factory_; | 181 pp::CompletionCallbackFactory<Decoder> callback_factory_; |
176 | 182 |
177 size_t encoded_data_next_pos_to_decode_; | 183 size_t encoded_data_next_pos_to_decode_; |
178 int next_picture_id_; | 184 int next_picture_id_; |
179 bool flushing_; | 185 bool flushing_; |
180 bool resetting_; | 186 bool resetting_; |
| 187 |
| 188 const PPB_Core* core_if_; |
| 189 static const int kMaxDecodeDelay = 128; |
| 190 PP_TimeTicks decode_time_[kMaxDecodeDelay]; |
| 191 PP_TimeTicks total_latency_; |
| 192 int num_pictures_; |
181 }; | 193 }; |
182 | 194 |
183 #if defined USE_VP8_TESTDATA_INSTEAD_OF_H264 | 195 #if defined USE_VP8_TESTDATA_INSTEAD_OF_H264 |
184 | 196 |
185 // VP8 is stored in an IVF container. | 197 // VP8 is stored in an IVF container. |
186 // Helpful description: http://wiki.multimedia.cx/index.php?title=IVF | 198 // Helpful description: http://wiki.multimedia.cx/index.php?title=IVF |
187 | 199 |
188 static void GetNextFrame(size_t* start_pos, size_t* end_pos) { | 200 static void GetNextFrame(size_t* start_pos, size_t* end_pos) { |
189 size_t current_pos = *start_pos; | 201 size_t current_pos = *start_pos; |
190 if (current_pos == 0) | 202 if (current_pos == 0) |
(...skipping 29 matching lines...) Expand all Loading... |
220 Decoder::Decoder(MyInstance* instance, | 232 Decoder::Decoder(MyInstance* instance, |
221 int id, | 233 int id, |
222 const pp::Graphics3D& graphics_3d) | 234 const pp::Graphics3D& graphics_3d) |
223 : instance_(instance), | 235 : instance_(instance), |
224 id_(id), | 236 id_(id), |
225 decoder_(new pp::VideoDecoder(instance)), | 237 decoder_(new pp::VideoDecoder(instance)), |
226 callback_factory_(this), | 238 callback_factory_(this), |
227 encoded_data_next_pos_to_decode_(0), | 239 encoded_data_next_pos_to_decode_(0), |
228 next_picture_id_(0), | 240 next_picture_id_(0), |
229 flushing_(false), | 241 flushing_(false), |
230 resetting_(false) { | 242 resetting_(false), |
| 243 total_latency_(0.0), |
| 244 num_pictures_(0) { |
| 245 core_if_ = static_cast<const PPB_Core*>( |
| 246 pp::Module::Get()->GetBrowserInterface(PPB_CORE_INTERFACE)); |
| 247 |
231 #if defined USE_VP8_TESTDATA_INSTEAD_OF_H264 | 248 #if defined USE_VP8_TESTDATA_INSTEAD_OF_H264 |
232 const PP_VideoProfile kBitstreamProfile = PP_VIDEOPROFILE_VP8MAIN; | 249 const PP_VideoProfile kBitstreamProfile = PP_VIDEOPROFILE_VP8MAIN; |
233 #else | 250 #else |
234 const PP_VideoProfile kBitstreamProfile = PP_VIDEOPROFILE_H264MAIN; | 251 const PP_VideoProfile kBitstreamProfile = PP_VIDEOPROFILE_H264MAIN; |
235 #endif | 252 #endif |
236 | 253 |
237 assert(!decoder_->is_null()); | 254 assert(!decoder_->is_null()); |
238 decoder_->Initialize(graphics_3d, | 255 decoder_->Initialize(graphics_3d, |
239 kBitstreamProfile, | 256 kBitstreamProfile, |
240 PP_TRUE /* allow_software_fallback */, | 257 PP_TRUE /* allow_software_fallback */, |
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
288 } | 305 } |
289 | 306 |
290 // Find the start of the next frame. | 307 // Find the start of the next frame. |
291 size_t start_pos = encoded_data_next_pos_to_decode_; | 308 size_t start_pos = encoded_data_next_pos_to_decode_; |
292 size_t end_pos; | 309 size_t end_pos; |
293 GetNextFrame(&start_pos, &end_pos); | 310 GetNextFrame(&start_pos, &end_pos); |
294 encoded_data_next_pos_to_decode_ = end_pos; | 311 encoded_data_next_pos_to_decode_ = end_pos; |
295 // Decode the frame. On completion, DecodeDone will call DecodeNextFrame | 312 // Decode the frame. On completion, DecodeDone will call DecodeNextFrame |
296 // to implement a decode loop. | 313 // to implement a decode loop. |
297 uint32_t size = static_cast<uint32_t>(end_pos - start_pos); | 314 uint32_t size = static_cast<uint32_t>(end_pos - start_pos); |
| 315 decode_time_[next_picture_id_ % kMaxDecodeDelay] = core_if_->GetTimeTicks(); |
298 decoder_->Decode(next_picture_id_++, | 316 decoder_->Decode(next_picture_id_++, |
299 size, | 317 size, |
300 kData + start_pos, | 318 kData + start_pos, |
301 callback_factory_.NewCallback(&Decoder::DecodeDone)); | 319 callback_factory_.NewCallback(&Decoder::DecodeDone)); |
302 } | 320 } |
303 } | 321 } |
304 | 322 |
305 void Decoder::DecodeDone(int32_t result) { | 323 void Decoder::DecodeDone(int32_t result) { |
306 assert(decoder_); | 324 assert(decoder_); |
307 // Break out of the decode loop on abort. | 325 // Break out of the decode loop on abort. |
308 if (result == PP_ERROR_ABORTED) | 326 if (result == PP_ERROR_ABORTED) |
309 return; | 327 return; |
310 assert(result == PP_OK); | 328 assert(result == PP_OK); |
311 if (!flushing_ && !resetting_) | 329 if (!flushing_ && !resetting_) |
312 DecodeNextFrame(); | 330 DecodeNextFrame(); |
313 } | 331 } |
314 | 332 |
315 void Decoder::PictureReady(int32_t result, PP_VideoPicture picture) { | 333 void Decoder::PictureReady(int32_t result, PP_VideoPicture picture) { |
316 assert(decoder_); | 334 assert(decoder_); |
317 // Break out of the get picture loop on abort. | 335 // Break out of the get picture loop on abort. |
318 if (result == PP_ERROR_ABORTED) | 336 if (result == PP_ERROR_ABORTED) |
319 return; | 337 return; |
320 assert(result == PP_OK); | 338 assert(result == PP_OK); |
| 339 |
| 340 num_pictures_++; |
| 341 PP_TimeTicks latency = core_if_->GetTimeTicks() - |
| 342 decode_time_[picture.decode_id % kMaxDecodeDelay]; |
| 343 total_latency_ += latency; |
| 344 |
321 decoder_->GetPicture( | 345 decoder_->GetPicture( |
322 callback_factory_.NewCallbackWithOutput(&Decoder::PictureReady)); | 346 callback_factory_.NewCallbackWithOutput(&Decoder::PictureReady)); |
323 instance_->PaintPicture(this, picture); | 347 instance_->PaintPicture(this, picture); |
324 } | 348 } |
325 | 349 |
326 void Decoder::FlushDone(int32_t result) { | 350 void Decoder::FlushDone(int32_t result) { |
327 assert(decoder_); | 351 assert(decoder_); |
328 assert(result == PP_OK || result == PP_ERROR_ABORTED); | 352 assert(result == PP_OK || result == PP_ERROR_ABORTED); |
329 assert(flushing_); | 353 assert(flushing_); |
330 flushing_ = false; | 354 flushing_ = false; |
(...skipping 11 matching lines...) Expand all Loading... |
342 MyInstance::MyInstance(PP_Instance instance, pp::Module* module) | 366 MyInstance::MyInstance(PP_Instance instance, pp::Module* module) |
343 : pp::Instance(instance), | 367 : pp::Instance(instance), |
344 pp::Graphics3DClient(this), | 368 pp::Graphics3DClient(this), |
345 is_painting_(false), | 369 is_painting_(false), |
346 num_frames_rendered_(0), | 370 num_frames_rendered_(0), |
347 first_frame_delivered_ticks_(-1), | 371 first_frame_delivered_ticks_(-1), |
348 last_swap_request_ticks_(-1), | 372 last_swap_request_ticks_(-1), |
349 swap_ticks_(0), | 373 swap_ticks_(0), |
350 callback_factory_(this), | 374 callback_factory_(this), |
351 context_(NULL) { | 375 context_(NULL) { |
352 assert((console_if_ = static_cast<const PPB_Console*>( | 376 console_if_ = static_cast<const PPB_Console*>( |
353 module->GetBrowserInterface(PPB_CONSOLE_INTERFACE)))); | 377 pp::Module::Get()->GetBrowserInterface(PPB_CONSOLE_INTERFACE)); |
354 assert((core_if_ = static_cast<const PPB_Core*>( | 378 core_if_ = static_cast<const PPB_Core*>( |
355 module->GetBrowserInterface(PPB_CORE_INTERFACE)))); | 379 pp::Module::Get()->GetBrowserInterface(PPB_CORE_INTERFACE)); |
356 assert((gles2_if_ = static_cast<const PPB_OpenGLES2*>( | 380 gles2_if_ = static_cast<const PPB_OpenGLES2*>( |
357 module->GetBrowserInterface(PPB_OPENGLES2_INTERFACE)))); | 381 pp::Module::Get()->GetBrowserInterface(PPB_OPENGLES2_INTERFACE)); |
| 382 |
358 RequestInputEvents(PP_INPUTEVENT_CLASS_MOUSE); | 383 RequestInputEvents(PP_INPUTEVENT_CLASS_MOUSE); |
359 } | 384 } |
360 | 385 |
361 MyInstance::~MyInstance() { | 386 MyInstance::~MyInstance() { |
362 if (!context_) | 387 if (!context_) |
363 return; | 388 return; |
364 | 389 |
365 PP_Resource graphics_3d = context_->pp_resource(); | 390 PP_Resource graphics_3d = context_->pp_resource(); |
366 if (shader_2d_.program) | 391 if (shader_2d_.program) |
367 gles2_if_->DeleteProgram(graphics_3d, shader_2d_.program); | 392 gles2_if_->DeleteProgram(graphics_3d, shader_2d_.program); |
368 if (shader_rectangle_arb_.program) | 393 if (shader_rectangle_arb_.program) |
369 gles2_if_->DeleteProgram(graphics_3d, shader_rectangle_arb_.program); | 394 gles2_if_->DeleteProgram(graphics_3d, shader_rectangle_arb_.program); |
| 395 if (shader_external_oes_.program) |
| 396 gles2_if_->DeleteProgram(graphics_3d, shader_external_oes_.program); |
370 | 397 |
371 for (DecoderList::iterator it = video_decoders_.begin(); | 398 for (DecoderList::iterator it = video_decoders_.begin(); |
372 it != video_decoders_.end(); | 399 it != video_decoders_.end(); |
373 ++it) | 400 ++it) |
374 delete *it; | 401 delete *it; |
375 | 402 |
376 delete context_; | 403 delete context_; |
377 } | 404 } |
378 | 405 |
379 void MyInstance::DidChangeView(const pp::Rect& position, | 406 void MyInstance::DidChangeView(const pp::Rect& position, |
(...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
448 x = half_width; | 475 x = half_width; |
449 y = half_height; | 476 y = half_height; |
450 } | 477 } |
451 | 478 |
452 PP_Resource graphics_3d = context_->pp_resource(); | 479 PP_Resource graphics_3d = context_->pp_resource(); |
453 if (picture.texture_target == GL_TEXTURE_2D) { | 480 if (picture.texture_target == GL_TEXTURE_2D) { |
454 Create2DProgramOnce(); | 481 Create2DProgramOnce(); |
455 gles2_if_->UseProgram(graphics_3d, shader_2d_.program); | 482 gles2_if_->UseProgram(graphics_3d, shader_2d_.program); |
456 gles2_if_->Uniform2f( | 483 gles2_if_->Uniform2f( |
457 graphics_3d, shader_2d_.texcoord_scale_location, 1.0, 1.0); | 484 graphics_3d, shader_2d_.texcoord_scale_location, 1.0, 1.0); |
458 } else { | 485 } else if (picture.texture_target == GL_TEXTURE_RECTANGLE_ARB) { |
459 assert(picture.texture_target == GL_TEXTURE_RECTANGLE_ARB); | |
460 CreateRectangleARBProgramOnce(); | 486 CreateRectangleARBProgramOnce(); |
461 gles2_if_->UseProgram(graphics_3d, shader_rectangle_arb_.program); | 487 gles2_if_->UseProgram(graphics_3d, shader_rectangle_arb_.program); |
462 gles2_if_->Uniform2f(graphics_3d, | 488 gles2_if_->Uniform2f(graphics_3d, |
463 shader_rectangle_arb_.texcoord_scale_location, | 489 shader_rectangle_arb_.texcoord_scale_location, |
464 picture.texture_size.width, | 490 picture.texture_size.width, |
465 picture.texture_size.height); | 491 picture.texture_size.height); |
| 492 } else { |
| 493 assert(picture.texture_target == GL_TEXTURE_EXTERNAL_OES); |
| 494 CreateExternalOESProgramOnce(); |
| 495 gles2_if_->UseProgram(graphics_3d, shader_external_oes_.program); |
| 496 gles2_if_->Uniform2f( |
| 497 graphics_3d, shader_external_oes_.texcoord_scale_location, 1.0, 1.0); |
466 } | 498 } |
467 | 499 |
468 gles2_if_->Viewport(graphics_3d, x, y, half_width, half_height); | 500 gles2_if_->Viewport(graphics_3d, x, y, half_width, half_height); |
469 gles2_if_->ActiveTexture(graphics_3d, GL_TEXTURE0); | 501 gles2_if_->ActiveTexture(graphics_3d, GL_TEXTURE0); |
470 gles2_if_->BindTexture( | 502 gles2_if_->BindTexture( |
471 graphics_3d, picture.texture_target, picture.texture_id); | 503 graphics_3d, picture.texture_target, picture.texture_id); |
472 gles2_if_->DrawArrays(graphics_3d, GL_TRIANGLE_STRIP, 0, 4); | 504 gles2_if_->DrawArrays(graphics_3d, GL_TRIANGLE_STRIP, 0, 4); |
473 | 505 |
474 gles2_if_->UseProgram(graphics_3d, 0); | 506 gles2_if_->UseProgram(graphics_3d, 0); |
475 | 507 |
476 last_swap_request_ticks_ = core_if_->GetTimeTicks(); | 508 last_swap_request_ticks_ = core_if_->GetTimeTicks(); |
477 context_->SwapBuffers( | 509 context_->SwapBuffers( |
478 callback_factory_.NewCallback(&MyInstance::PaintFinished)); | 510 callback_factory_.NewCallback(&MyInstance::PaintFinished)); |
479 } | 511 } |
480 | 512 |
481 void MyInstance::PaintFinished(int32_t result) { | 513 void MyInstance::PaintFinished(int32_t result) { |
482 assert(result == PP_OK); | 514 assert(result == PP_OK); |
483 swap_ticks_ += core_if_->GetTimeTicks() - last_swap_request_ticks_; | 515 swap_ticks_ += core_if_->GetTimeTicks() - last_swap_request_ticks_; |
484 is_painting_ = false; | 516 is_painting_ = false; |
485 ++num_frames_rendered_; | 517 ++num_frames_rendered_; |
486 if (num_frames_rendered_ % 50 == 0) { | 518 if (num_frames_rendered_ % 50 == 0) { |
487 double elapsed = core_if_->GetTimeTicks() - first_frame_delivered_ticks_; | 519 double elapsed = core_if_->GetTimeTicks() - first_frame_delivered_ticks_; |
488 double fps = (elapsed > 0) ? num_frames_rendered_ / elapsed : 1000; | 520 double fps = (elapsed > 0) ? num_frames_rendered_ / elapsed : 1000; |
489 double ms_per_swap = (swap_ticks_ * 1e3) / num_frames_rendered_; | 521 double ms_per_swap = (swap_ticks_ * 1e3) / num_frames_rendered_; |
| 522 double secs_average_latency = 0; |
| 523 for (DecoderList::iterator it = video_decoders_.begin(); |
| 524 it != video_decoders_.end(); |
| 525 ++it) |
| 526 secs_average_latency += (*it)->GetAverageLatency(); |
| 527 secs_average_latency /= video_decoders_.size(); |
| 528 double ms_average_latency = 1000 * secs_average_latency; |
490 LogError(this).s() << "Rendered frames: " << num_frames_rendered_ | 529 LogError(this).s() << "Rendered frames: " << num_frames_rendered_ |
491 << ", fps: " << fps | 530 << ", fps: " << fps |
492 << ", with average ms/swap of: " << ms_per_swap; | 531 << ", with average ms/swap of: " << ms_per_swap |
| 532 << ", with average latency (ms) of: " |
| 533 << ms_average_latency; |
493 } | 534 } |
494 | 535 |
495 // If the decoders were reset, this will be empty. | 536 // If the decoders were reset, this will be empty. |
496 if (pending_pictures_.empty()) | 537 if (pending_pictures_.empty()) |
497 return; | 538 return; |
498 | 539 |
499 const PendingPicture& next = pending_pictures_.front(); | 540 const PendingPicture& next = pending_pictures_.front(); |
500 Decoder* decoder = next.decoder; | 541 Decoder* decoder = next.decoder; |
501 const PP_VideoPicture& picture = next.picture; | 542 const PP_VideoPicture& picture = next.picture; |
502 decoder->RecyclePicture(picture); | 543 decoder->RecyclePicture(picture); |
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
535 | 576 |
536 assertNoGLError(); | 577 assertNoGLError(); |
537 | 578 |
538 CreateGLObjects(); | 579 CreateGLObjects(); |
539 } | 580 } |
540 | 581 |
541 void MyInstance::CreateGLObjects() { | 582 void MyInstance::CreateGLObjects() { |
542 // Assign vertex positions and texture coordinates to buffers for use in | 583 // Assign vertex positions and texture coordinates to buffers for use in |
543 // shader program. | 584 // shader program. |
544 static const float kVertices[] = { | 585 static const float kVertices[] = { |
545 -1, 1, -1, -1, 1, 1, 1, -1, // Position coordinates. | 586 -1, -1, -1, 1, 1, -1, 1, 1, // Position coordinates. |
546 0, 1, 0, 0, 1, 1, 1, 0, // Texture coordinates. | 587 0, 1, 0, 0, 1, 1, 1, 0, // Texture coordinates. |
547 }; | 588 }; |
548 | 589 |
549 GLuint buffer; | 590 GLuint buffer; |
550 gles2_if_->GenBuffers(context_->pp_resource(), 1, &buffer); | 591 gles2_if_->GenBuffers(context_->pp_resource(), 1, &buffer); |
551 gles2_if_->BindBuffer(context_->pp_resource(), GL_ARRAY_BUFFER, buffer); | 592 gles2_if_->BindBuffer(context_->pp_resource(), GL_ARRAY_BUFFER, buffer); |
552 | 593 |
553 gles2_if_->BufferData(context_->pp_resource(), | 594 gles2_if_->BufferData(context_->pp_resource(), |
554 GL_ARRAY_BUFFER, | 595 GL_ARRAY_BUFFER, |
555 sizeof(kVertices), | 596 sizeof(kVertices), |
556 kVertices, | 597 kVertices, |
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
591 "#extension GL_ARB_texture_rectangle : require\n" | 632 "#extension GL_ARB_texture_rectangle : require\n" |
592 "precision mediump float; \n" | 633 "precision mediump float; \n" |
593 "varying vec2 v_texCoord; \n" | 634 "varying vec2 v_texCoord; \n" |
594 "uniform sampler2DRect s_texture; \n" | 635 "uniform sampler2DRect s_texture; \n" |
595 "void main() \n" | 636 "void main() \n" |
596 "{" | 637 "{" |
597 " gl_FragColor = texture2DRect(s_texture, v_texCoord).rgba; \n" | 638 " gl_FragColor = texture2DRect(s_texture, v_texCoord).rgba; \n" |
598 "}"; | 639 "}"; |
599 shader_rectangle_arb_ = | 640 shader_rectangle_arb_ = |
600 CreateProgram(kVertexShader, kFragmentShaderRectangle); | 641 CreateProgram(kVertexShader, kFragmentShaderRectangle); |
| 642 assertNoGLError(); |
| 643 } |
| 644 |
| 645 void MyInstance::CreateExternalOESProgramOnce() { |
| 646 if (shader_external_oes_.program) |
| 647 return; |
| 648 static const char kFragmentShaderExternal[] = |
| 649 "#extension GL_OES_EGL_image_external : require\n" |
| 650 "precision mediump float; \n" |
| 651 "varying vec2 v_texCoord; \n" |
| 652 "uniform samplerExternalOES s_texture; \n" |
| 653 "void main() \n" |
| 654 "{" |
| 655 " gl_FragColor = texture2D(s_texture, v_texCoord); \n" |
| 656 "}"; |
| 657 shader_external_oes_ = CreateProgram(kVertexShader, kFragmentShaderExternal); |
| 658 assertNoGLError(); |
601 } | 659 } |
602 | 660 |
603 Shader MyInstance::CreateProgram(const char* vertex_shader, | 661 Shader MyInstance::CreateProgram(const char* vertex_shader, |
604 const char* fragment_shader) { | 662 const char* fragment_shader) { |
605 Shader shader; | 663 Shader shader; |
606 | 664 |
607 // Create shader program. | 665 // Create shader program. |
608 shader.program = gles2_if_->CreateProgram(context_->pp_resource()); | 666 shader.program = gles2_if_->CreateProgram(context_->pp_resource()); |
609 CreateShader( | 667 CreateShader( |
610 shader.program, GL_VERTEX_SHADER, vertex_shader, strlen(vertex_shader)); | 668 shader.program, GL_VERTEX_SHADER, vertex_shader, strlen(vertex_shader)); |
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
672 }; | 730 }; |
673 | 731 |
674 } // anonymous namespace | 732 } // anonymous namespace |
675 | 733 |
676 namespace pp { | 734 namespace pp { |
677 // Factory function for your specialization of the Module object. | 735 // Factory function for your specialization of the Module object. |
678 Module* CreateModule() { | 736 Module* CreateModule() { |
679 return new MyModule(); | 737 return new MyModule(); |
680 } | 738 } |
681 } // namespace pp | 739 } // namespace pp |
OLD | NEW |