OLD | NEW |
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 <string.h> | 5 #include <string.h> |
6 | 6 |
7 #include <iostream> | 7 #include <iostream> |
8 #include <sstream> | 8 #include <sstream> |
9 #include <list> | 9 #include <list> |
10 #include <map> | 10 #include <map> |
11 #include <set> | 11 #include <set> |
12 #include <vector> | 12 #include <vector> |
13 | 13 |
14 #include "ppapi/c/dev/ppb_console_dev.h" | 14 #include "ppapi/c/dev/ppb_console_dev.h" |
15 #include "ppapi/c/pp_errors.h" | 15 #include "ppapi/c/pp_errors.h" |
16 #include "ppapi/c/ppb_opengles2.h" | 16 #include "ppapi/c/ppb_opengles2.h" |
17 #include "ppapi/cpp/dev/video_decoder_client_dev.h" | 17 #include "ppapi/cpp/dev/video_decoder_client_dev.h" |
18 #include "ppapi/cpp/dev/video_decoder_dev.h" | 18 #include "ppapi/cpp/dev/video_decoder_dev.h" |
19 #include "ppapi/cpp/graphics_3d.h" | 19 #include "ppapi/cpp/graphics_3d.h" |
20 #include "ppapi/cpp/graphics_3d_client.h" | 20 #include "ppapi/cpp/graphics_3d_client.h" |
21 #include "ppapi/cpp/instance.h" | 21 #include "ppapi/cpp/instance.h" |
22 #include "ppapi/cpp/module.h" | 22 #include "ppapi/cpp/module.h" |
23 #include "ppapi/cpp/rect.h" | 23 #include "ppapi/cpp/rect.h" |
24 #include "ppapi/cpp/var.h" | 24 #include "ppapi/cpp/var.h" |
25 #include "ppapi/examples/video_decode/testdata.h" | 25 #include "ppapi/examples/video_decode/testdata.h" |
26 #include "ppapi/lib/gl/include/GLES2/gl2.h" | 26 #include "ppapi/lib/gl/include/GLES2/gl2.h" |
| 27 #include "ppapi/lib/gl/include/GLES2/gl2ext.h" |
27 #include "ppapi/utility/completion_callback_factory.h" | 28 #include "ppapi/utility/completion_callback_factory.h" |
28 | 29 |
29 // Use assert as a poor-man's CHECK, even in non-debug mode. | 30 // Use assert as a poor-man's CHECK, even in non-debug mode. |
30 // Since <assert.h> redefines assert on every inclusion (it doesn't use | 31 // Since <assert.h> redefines assert on every inclusion (it doesn't use |
31 // include-guards), make sure this is the last file #include'd in this file. | 32 // include-guards), make sure this is the last file #include'd in this file. |
32 #undef NDEBUG | 33 #undef NDEBUG |
33 #include <assert.h> | 34 #include <assert.h> |
34 | 35 |
35 // Assert |context_| isn't holding any GL Errors. Done as a macro instead of a | 36 // Assert |context_| isn't holding any GL Errors. Done as a macro instead of a |
36 // function to preserve line number information in the failure message. | 37 // function to preserve line number information in the failure message. |
37 #define assertNoGLError() \ | 38 #define assertNoGLError() \ |
38 assert(!gles2_if_->GetError(context_->pp_resource())); | 39 assert(!gles2_if_->GetError(context_->pp_resource())); |
39 | 40 |
40 namespace { | 41 namespace { |
41 | 42 |
| 43 struct PictureBufferInfo { |
| 44 PP_PictureBuffer_Dev buffer; |
| 45 GLenum texture_target; |
| 46 }; |
| 47 |
| 48 struct Shader { |
| 49 Shader() : program(0), |
| 50 texcoord_scale_location(0) {} |
| 51 |
| 52 GLuint program; |
| 53 GLint texcoord_scale_location; |
| 54 }; |
| 55 |
42 class VideoDecodeDemoInstance : public pp::Instance, | 56 class VideoDecodeDemoInstance : public pp::Instance, |
43 public pp::Graphics3DClient, | 57 public pp::Graphics3DClient, |
44 public pp::VideoDecoderClient_Dev { | 58 public pp::VideoDecoderClient_Dev { |
45 public: | 59 public: |
46 VideoDecodeDemoInstance(PP_Instance instance, pp::Module* module); | 60 VideoDecodeDemoInstance(PP_Instance instance, pp::Module* module); |
47 virtual ~VideoDecodeDemoInstance(); | 61 virtual ~VideoDecodeDemoInstance(); |
48 | 62 |
49 // pp::Instance implementation (see PPP_Instance). | 63 // pp::Instance implementation (see PPP_Instance). |
50 virtual void DidChangeView(const pp::Rect& position, | 64 virtual void DidChangeView(const pp::Rect& position, |
51 const pp::Rect& clip_ignored); | 65 const pp::Rect& clip_ignored); |
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
83 | 97 |
84 void DecodeNextNALUs(); | 98 void DecodeNextNALUs(); |
85 | 99 |
86 // Per-decoder implementation of part of pp::VideoDecoderClient_Dev. | 100 // Per-decoder implementation of part of pp::VideoDecoderClient_Dev. |
87 void ProvidePictureBuffers( | 101 void ProvidePictureBuffers( |
88 uint32_t req_num_of_bufs, | 102 uint32_t req_num_of_bufs, |
89 PP_Size dimensions, | 103 PP_Size dimensions, |
90 uint32_t texture_target); | 104 uint32_t texture_target); |
91 void DismissPictureBuffer(int32_t picture_buffer_id); | 105 void DismissPictureBuffer(int32_t picture_buffer_id); |
92 | 106 |
93 const PP_PictureBuffer_Dev& GetPictureBufferById(int id); | 107 const PictureBufferInfo& GetPictureBufferInfoById(int id); |
94 pp::VideoDecoder_Dev* decoder() { return decoder_; } | 108 pp::VideoDecoder_Dev* decoder() { return decoder_; } |
95 | 109 |
96 private: | 110 private: |
97 void DecodeNextNALU(); | 111 void DecodeNextNALU(); |
98 static void GetNextNALUBoundary(size_t start_pos, size_t* end_pos); | 112 static void GetNextNALUBoundary(size_t start_pos, size_t* end_pos); |
99 void DecoderBitstreamDone(int32_t result, int bitstream_buffer_id); | 113 void DecoderBitstreamDone(int32_t result, int bitstream_buffer_id); |
100 void DecoderFlushDone(int32_t result); | 114 void DecoderFlushDone(int32_t result); |
101 | 115 |
102 VideoDecodeDemoInstance* gles2_; | 116 VideoDecodeDemoInstance* gles2_; |
103 pp::VideoDecoder_Dev* decoder_; | 117 pp::VideoDecoder_Dev* decoder_; |
104 pp::CompletionCallbackFactory<DecoderClient> callback_factory_; | 118 pp::CompletionCallbackFactory<DecoderClient> callback_factory_; |
105 int next_picture_buffer_id_; | 119 int next_picture_buffer_id_; |
106 int next_bitstream_buffer_id_; | 120 int next_bitstream_buffer_id_; |
107 size_t encoded_data_next_pos_to_decode_; | 121 size_t encoded_data_next_pos_to_decode_; |
108 std::set<int> bitstream_ids_at_decoder_; | 122 std::set<int> bitstream_ids_at_decoder_; |
109 // Map of texture buffers indexed by buffer id. | 123 // Map of texture buffers indexed by buffer id. |
110 typedef std::map<int, PP_PictureBuffer_Dev> PictureBufferMap; | 124 typedef std::map<int, PictureBufferInfo> PictureBufferMap; |
111 PictureBufferMap picture_buffers_by_id_; | 125 PictureBufferMap picture_buffers_by_id_; |
112 // Map of bitstream buffers indexed by id. | 126 // Map of bitstream buffers indexed by id. |
113 typedef std::map<int, pp::Buffer_Dev*> BitstreamBufferMap; | 127 typedef std::map<int, pp::Buffer_Dev*> BitstreamBufferMap; |
114 BitstreamBufferMap bitstream_buffers_by_id_; | 128 BitstreamBufferMap bitstream_buffers_by_id_; |
115 }; | 129 }; |
116 | 130 |
117 // Initialize Video Decoders. | 131 // Initialize Video Decoders. |
118 void InitializeDecoders(); | 132 void InitializeDecoders(); |
119 | 133 |
120 // GL-related functions. | 134 // GL-related functions. |
121 void InitGL(); | 135 void InitGL(); |
122 GLuint CreateTexture(int32_t width, int32_t height); | 136 GLuint CreateTexture(int32_t width, int32_t height, GLenum texture_target); |
123 void CreateGLObjects(); | 137 void CreateGLObjects(); |
| 138 Shader CreateProgram(const char* vertex_shader, |
| 139 const char* fragment_shader); |
124 void CreateShader(GLuint program, GLenum type, const char* source, int size); | 140 void CreateShader(GLuint program, GLenum type, const char* source, int size); |
125 void DeleteTexture(GLuint id); | 141 void DeleteTexture(GLuint id); |
126 void PaintFinished(int32_t result, PP_Resource decoder, | 142 void PaintFinished(int32_t result, PP_Resource decoder, |
127 int picture_buffer_id); | 143 int picture_buffer_id); |
128 | 144 |
129 // Log an error to the developer console and stderr (though the latter may be | 145 // Log an error to the developer console and stderr (though the latter may be |
130 // closed due to sandboxing or blackholed for other reasons) by creating a | 146 // closed due to sandboxing or blackholed for other reasons) by creating a |
131 // temporary of this type and streaming to it. Example usage: | 147 // temporary of this type and streaming to it. Example usage: |
132 // LogError(this).s() << "Hello world: " << 42; | 148 // LogError(this).s() << "Hello world: " << 42; |
133 class LogError { | 149 class LogError { |
(...skipping 27 matching lines...) Expand all Loading... |
161 | 177 |
162 // Unowned pointers. | 178 // Unowned pointers. |
163 const PPB_Console_Dev* console_if_; | 179 const PPB_Console_Dev* console_if_; |
164 const PPB_Core* core_if_; | 180 const PPB_Core* core_if_; |
165 const PPB_OpenGLES2* gles2_if_; | 181 const PPB_OpenGLES2* gles2_if_; |
166 | 182 |
167 // Owned data. | 183 // Owned data. |
168 pp::Graphics3D* context_; | 184 pp::Graphics3D* context_; |
169 typedef std::map<int, DecoderClient*> Decoders; | 185 typedef std::map<int, DecoderClient*> Decoders; |
170 Decoders video_decoders_; | 186 Decoders video_decoders_; |
| 187 |
| 188 // Shader program to draw GL_TEXTURE_2D target. |
| 189 Shader shader_2d_; |
| 190 // Shader program to draw GL_TEXTURE_RECTANGLE_ARB target. |
| 191 Shader shader_rectangle_arb_; |
171 }; | 192 }; |
172 | 193 |
173 VideoDecodeDemoInstance::DecoderClient::DecoderClient( | 194 VideoDecodeDemoInstance::DecoderClient::DecoderClient( |
174 VideoDecodeDemoInstance* gles2, pp::VideoDecoder_Dev* decoder) | 195 VideoDecodeDemoInstance* gles2, pp::VideoDecoder_Dev* decoder) |
175 : gles2_(gles2), decoder_(decoder), callback_factory_(this), | 196 : gles2_(gles2), decoder_(decoder), callback_factory_(this), |
176 next_picture_buffer_id_(0), | 197 next_picture_buffer_id_(0), |
177 next_bitstream_buffer_id_(0), encoded_data_next_pos_to_decode_(0) { | 198 next_bitstream_buffer_id_(0), encoded_data_next_pos_to_decode_(0) { |
178 } | 199 } |
179 | 200 |
180 VideoDecodeDemoInstance::DecoderClient::~DecoderClient() { | 201 VideoDecodeDemoInstance::DecoderClient::~DecoderClient() { |
181 delete decoder_; | 202 delete decoder_; |
182 decoder_ = NULL; | 203 decoder_ = NULL; |
183 | 204 |
184 for (BitstreamBufferMap::iterator it = bitstream_buffers_by_id_.begin(); | 205 for (BitstreamBufferMap::iterator it = bitstream_buffers_by_id_.begin(); |
185 it != bitstream_buffers_by_id_.end(); ++it) { | 206 it != bitstream_buffers_by_id_.end(); ++it) { |
186 delete it->second; | 207 delete it->second; |
187 } | 208 } |
188 bitstream_buffers_by_id_.clear(); | 209 bitstream_buffers_by_id_.clear(); |
189 | 210 |
190 for (PictureBufferMap::iterator it = picture_buffers_by_id_.begin(); | 211 for (PictureBufferMap::iterator it = picture_buffers_by_id_.begin(); |
191 it != picture_buffers_by_id_.end(); ++it) { | 212 it != picture_buffers_by_id_.end(); ++it) { |
192 gles2_->DeleteTexture(it->second.texture_id); | 213 gles2_->DeleteTexture(it->second.buffer.texture_id); |
193 } | 214 } |
194 picture_buffers_by_id_.clear(); | 215 picture_buffers_by_id_.clear(); |
195 } | 216 } |
196 | 217 |
197 VideoDecodeDemoInstance::VideoDecodeDemoInstance(PP_Instance instance, | 218 VideoDecodeDemoInstance::VideoDecodeDemoInstance(PP_Instance instance, |
198 pp::Module* module) | 219 pp::Module* module) |
199 : pp::Instance(instance), pp::Graphics3DClient(this), | 220 : pp::Instance(instance), pp::Graphics3DClient(this), |
200 pp::VideoDecoderClient_Dev(this), | 221 pp::VideoDecoderClient_Dev(this), |
201 num_frames_rendered_(0), | 222 num_frames_rendered_(0), |
202 first_frame_delivered_ticks_(-1), | 223 first_frame_delivered_ticks_(-1), |
203 swap_ticks_(0), | 224 swap_ticks_(0), |
204 callback_factory_(this), | 225 callback_factory_(this), |
205 context_(NULL) { | 226 context_(NULL) { |
206 assert((console_if_ = static_cast<const PPB_Console_Dev*>( | 227 assert((console_if_ = static_cast<const PPB_Console_Dev*>( |
207 module->GetBrowserInterface(PPB_CONSOLE_DEV_INTERFACE)))); | 228 module->GetBrowserInterface(PPB_CONSOLE_DEV_INTERFACE)))); |
208 assert((core_if_ = static_cast<const PPB_Core*>( | 229 assert((core_if_ = static_cast<const PPB_Core*>( |
209 module->GetBrowserInterface(PPB_CORE_INTERFACE)))); | 230 module->GetBrowserInterface(PPB_CORE_INTERFACE)))); |
210 assert((gles2_if_ = static_cast<const PPB_OpenGLES2*>( | 231 assert((gles2_if_ = static_cast<const PPB_OpenGLES2*>( |
211 module->GetBrowserInterface(PPB_OPENGLES2_INTERFACE)))); | 232 module->GetBrowserInterface(PPB_OPENGLES2_INTERFACE)))); |
212 } | 233 } |
213 | 234 |
214 VideoDecodeDemoInstance::~VideoDecodeDemoInstance() { | 235 VideoDecodeDemoInstance::~VideoDecodeDemoInstance() { |
| 236 if (shader_2d_.program) |
| 237 gles2_if_->DeleteProgram(context_->pp_resource(), shader_2d_.program); |
| 238 if (shader_rectangle_arb_.program) { |
| 239 gles2_if_->DeleteProgram( |
| 240 context_->pp_resource(), shader_rectangle_arb_.program); |
| 241 } |
| 242 |
215 for (Decoders::iterator it = video_decoders_.begin(); | 243 for (Decoders::iterator it = video_decoders_.begin(); |
216 it != video_decoders_.end(); ++it) { | 244 it != video_decoders_.end(); ++it) { |
217 delete it->second; | 245 delete it->second; |
218 } | 246 } |
219 video_decoders_.clear(); | 247 video_decoders_.clear(); |
220 delete context_; | 248 delete context_; |
221 } | 249 } |
222 | 250 |
223 void VideoDecodeDemoInstance::DidChangeView( | 251 void VideoDecodeDemoInstance::DidChangeView( |
224 const pp::Rect& position, const pp::Rect& clip_ignored) { | 252 const pp::Rect& position, const pp::Rect& clip_ignored) { |
(...skipping 105 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
330 uint32_t texture_target) { | 358 uint32_t texture_target) { |
331 DecoderClient* client = video_decoders_[decoder]; | 359 DecoderClient* client = video_decoders_[decoder]; |
332 assert(client); | 360 assert(client); |
333 client->ProvidePictureBuffers(req_num_of_bufs, dimensions, texture_target); | 361 client->ProvidePictureBuffers(req_num_of_bufs, dimensions, texture_target); |
334 } | 362 } |
335 | 363 |
336 void VideoDecodeDemoInstance::DecoderClient::ProvidePictureBuffers( | 364 void VideoDecodeDemoInstance::DecoderClient::ProvidePictureBuffers( |
337 uint32_t req_num_of_bufs, | 365 uint32_t req_num_of_bufs, |
338 PP_Size dimensions, | 366 PP_Size dimensions, |
339 uint32_t texture_target) { | 367 uint32_t texture_target) { |
340 // TODO(sail): Add support for GL_TEXTURE_RECTANGLE_ARB. | |
341 assert(texture_target == GL_TEXTURE_2D); | |
342 std::vector<PP_PictureBuffer_Dev> buffers; | 368 std::vector<PP_PictureBuffer_Dev> buffers; |
343 for (uint32_t i = 0; i < req_num_of_bufs; ++i) { | 369 for (uint32_t i = 0; i < req_num_of_bufs; ++i) { |
344 PP_PictureBuffer_Dev buffer; | 370 PictureBufferInfo info; |
345 buffer.size = dimensions; | 371 info.buffer.size = dimensions; |
346 buffer.texture_id = | 372 info.texture_target = texture_target; |
347 gles2_->CreateTexture(dimensions.width, dimensions.height); | 373 info.buffer.texture_id = gles2_->CreateTexture( |
| 374 dimensions.width, dimensions.height, info.texture_target); |
348 int id = ++next_picture_buffer_id_; | 375 int id = ++next_picture_buffer_id_; |
349 buffer.id = id; | 376 info.buffer.id = id; |
350 buffers.push_back(buffer); | 377 buffers.push_back(info.buffer); |
351 assert(picture_buffers_by_id_.insert(std::make_pair(id, buffer)).second); | 378 assert(picture_buffers_by_id_.insert(std::make_pair(id, info)).second); |
352 } | 379 } |
353 decoder_->AssignPictureBuffers(buffers); | 380 decoder_->AssignPictureBuffers(buffers); |
354 } | 381 } |
355 | 382 |
356 const PP_PictureBuffer_Dev& | 383 const PictureBufferInfo& |
357 VideoDecodeDemoInstance::DecoderClient::GetPictureBufferById( | 384 VideoDecodeDemoInstance::DecoderClient::GetPictureBufferInfoById( |
358 int id) { | 385 int id) { |
359 PictureBufferMap::iterator it = picture_buffers_by_id_.find(id); | 386 PictureBufferMap::iterator it = picture_buffers_by_id_.find(id); |
360 assert(it != picture_buffers_by_id_.end()); | 387 assert(it != picture_buffers_by_id_.end()); |
361 return it->second; | 388 return it->second; |
362 } | 389 } |
363 | 390 |
364 void VideoDecodeDemoInstance::DismissPictureBuffer(PP_Resource decoder, | 391 void VideoDecodeDemoInstance::DismissPictureBuffer(PP_Resource decoder, |
365 int32_t picture_buffer_id) { | 392 int32_t picture_buffer_id) { |
366 DecoderClient* client = video_decoders_[decoder]; | 393 DecoderClient* client = video_decoders_[decoder]; |
367 assert(client); | 394 assert(client); |
368 client->DismissPictureBuffer(picture_buffer_id); | 395 client->DismissPictureBuffer(picture_buffer_id); |
369 } | 396 } |
370 | 397 |
371 void VideoDecodeDemoInstance::DecoderClient::DismissPictureBuffer( | 398 void VideoDecodeDemoInstance::DecoderClient::DismissPictureBuffer( |
372 int32_t picture_buffer_id) { | 399 int32_t picture_buffer_id) { |
373 gles2_->DeleteTexture(GetPictureBufferById(picture_buffer_id).texture_id); | 400 gles2_->DeleteTexture(GetPictureBufferInfoById( |
| 401 picture_buffer_id).buffer.texture_id); |
374 picture_buffers_by_id_.erase(picture_buffer_id); | 402 picture_buffers_by_id_.erase(picture_buffer_id); |
375 } | 403 } |
376 | 404 |
377 void VideoDecodeDemoInstance::PictureReady(PP_Resource decoder, | 405 void VideoDecodeDemoInstance::PictureReady(PP_Resource decoder, |
378 const PP_Picture_Dev& picture) { | 406 const PP_Picture_Dev& picture) { |
379 if (first_frame_delivered_ticks_ == -1) | 407 if (first_frame_delivered_ticks_ == -1) |
380 assert((first_frame_delivered_ticks_ = core_if_->GetTimeTicks()) != -1); | 408 assert((first_frame_delivered_ticks_ = core_if_->GetTimeTicks()) != -1); |
381 if (is_painting_) { | 409 if (is_painting_) { |
382 pictures_pending_paint_.push_back(std::make_pair(decoder, picture)); | 410 pictures_pending_paint_.push_back(std::make_pair(decoder, picture)); |
383 return; | 411 return; |
384 } | 412 } |
385 DecoderClient* client = video_decoders_[decoder]; | 413 DecoderClient* client = video_decoders_[decoder]; |
386 assert(client); | 414 assert(client); |
387 const PP_PictureBuffer_Dev& buffer = | 415 const PictureBufferInfo& info = |
388 client->GetPictureBufferById(picture.picture_buffer_id); | 416 client->GetPictureBufferInfoById(picture.picture_buffer_id); |
389 assert(!is_painting_); | 417 assert(!is_painting_); |
390 is_painting_ = true; | 418 is_painting_ = true; |
391 int x = 0; | 419 int x = 0; |
392 int y = 0; | 420 int y = 0; |
393 if (client != video_decoders_.begin()->second) { | 421 if (client != video_decoders_.begin()->second) { |
394 x = plugin_size_.width() / kNumDecoders; | 422 x = plugin_size_.width() / kNumDecoders; |
395 y = plugin_size_.height() / kNumDecoders; | 423 y = plugin_size_.height() / kNumDecoders; |
396 } | 424 } |
397 | 425 |
| 426 if (info.texture_target == GL_TEXTURE_2D) { |
| 427 gles2_if_->UseProgram(context_->pp_resource(), shader_2d_.program); |
| 428 gles2_if_->Uniform2f( |
| 429 context_->pp_resource(), shader_2d_.texcoord_scale_location, 1.0, 1.0); |
| 430 } else { |
| 431 assert(info.texture_target == GL_TEXTURE_RECTANGLE_ARB); |
| 432 gles2_if_->UseProgram( |
| 433 context_->pp_resource(), shader_rectangle_arb_.program); |
| 434 gles2_if_->Uniform2f(context_->pp_resource(), |
| 435 shader_rectangle_arb_.texcoord_scale_location, |
| 436 info.buffer.size.width, |
| 437 info.buffer.size.height); |
| 438 } |
| 439 |
398 gles2_if_->Viewport(context_->pp_resource(), x, y, | 440 gles2_if_->Viewport(context_->pp_resource(), x, y, |
399 plugin_size_.width() / kNumDecoders, | 441 plugin_size_.width() / kNumDecoders, |
400 plugin_size_.height() / kNumDecoders); | 442 plugin_size_.height() / kNumDecoders); |
401 gles2_if_->ActiveTexture(context_->pp_resource(), GL_TEXTURE0); | 443 gles2_if_->ActiveTexture(context_->pp_resource(), GL_TEXTURE0); |
402 gles2_if_->BindTexture( | 444 gles2_if_->BindTexture( |
403 context_->pp_resource(), GL_TEXTURE_2D, buffer.texture_id); | 445 context_->pp_resource(), info.texture_target, info.buffer.texture_id); |
404 gles2_if_->DrawArrays(context_->pp_resource(), GL_TRIANGLE_STRIP, 0, 4); | 446 gles2_if_->DrawArrays(context_->pp_resource(), GL_TRIANGLE_STRIP, 0, 4); |
| 447 |
| 448 gles2_if_->UseProgram(context_->pp_resource(), 0); |
| 449 |
405 pp::CompletionCallback cb = | 450 pp::CompletionCallback cb = |
406 callback_factory_.NewCallback( | 451 callback_factory_.NewCallback( |
407 &VideoDecodeDemoInstance::PaintFinished, decoder, buffer.id); | 452 &VideoDecodeDemoInstance::PaintFinished, decoder, info.buffer.id); |
408 last_swap_request_ticks_ = core_if_->GetTimeTicks(); | 453 last_swap_request_ticks_ = core_if_->GetTimeTicks(); |
409 assert(context_->SwapBuffers(cb) == PP_OK_COMPLETIONPENDING); | 454 assert(context_->SwapBuffers(cb) == PP_OK_COMPLETIONPENDING); |
410 } | 455 } |
411 | 456 |
412 void VideoDecodeDemoInstance::NotifyError(PP_Resource decoder, | 457 void VideoDecodeDemoInstance::NotifyError(PP_Resource decoder, |
413 PP_VideoDecodeError_Dev error) { | 458 PP_VideoDecodeError_Dev error) { |
414 LogError(this).s() << "Received error: " << error; | 459 LogError(this).s() << "Received error: " << error; |
415 assert(!"Unexpected error; see stderr for details"); | 460 assert(!"Unexpected error; see stderr for details"); |
416 } | 461 } |
417 | 462 |
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
476 if (client && client->decoder()) | 521 if (client && client->decoder()) |
477 client->decoder()->ReusePictureBuffer(picture_buffer_id); | 522 client->decoder()->ReusePictureBuffer(picture_buffer_id); |
478 if (!pictures_pending_paint_.empty()) { | 523 if (!pictures_pending_paint_.empty()) { |
479 std::pair<PP_Resource, PP_Picture_Dev> decoder_picture = | 524 std::pair<PP_Resource, PP_Picture_Dev> decoder_picture = |
480 pictures_pending_paint_.front(); | 525 pictures_pending_paint_.front(); |
481 pictures_pending_paint_.pop_front(); | 526 pictures_pending_paint_.pop_front(); |
482 PictureReady(decoder_picture.first, decoder_picture.second); | 527 PictureReady(decoder_picture.first, decoder_picture.second); |
483 } | 528 } |
484 } | 529 } |
485 | 530 |
486 GLuint VideoDecodeDemoInstance::CreateTexture(int32_t width, int32_t height) { | 531 GLuint VideoDecodeDemoInstance::CreateTexture(int32_t width, |
| 532 int32_t height, |
| 533 GLenum texture_target) { |
487 GLuint texture_id; | 534 GLuint texture_id; |
488 gles2_if_->GenTextures(context_->pp_resource(), 1, &texture_id); | 535 gles2_if_->GenTextures(context_->pp_resource(), 1, &texture_id); |
489 assertNoGLError(); | 536 assertNoGLError(); |
490 // Assign parameters. | 537 // Assign parameters. |
491 gles2_if_->ActiveTexture(context_->pp_resource(), GL_TEXTURE0); | 538 gles2_if_->ActiveTexture(context_->pp_resource(), GL_TEXTURE0); |
492 gles2_if_->BindTexture(context_->pp_resource(), GL_TEXTURE_2D, texture_id); | 539 gles2_if_->BindTexture(context_->pp_resource(), texture_target, texture_id); |
493 gles2_if_->TexParameteri( | 540 gles2_if_->TexParameteri( |
494 context_->pp_resource(), GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, | 541 context_->pp_resource(), texture_target, GL_TEXTURE_MIN_FILTER, |
495 GL_NEAREST); | 542 GL_NEAREST); |
496 gles2_if_->TexParameteri( | 543 gles2_if_->TexParameteri( |
497 context_->pp_resource(), GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, | 544 context_->pp_resource(), texture_target, GL_TEXTURE_MAG_FILTER, |
498 GL_NEAREST); | 545 GL_NEAREST); |
499 gles2_if_->TexParameterf( | 546 gles2_if_->TexParameterf( |
500 context_->pp_resource(), GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, | 547 context_->pp_resource(), texture_target, GL_TEXTURE_WRAP_S, |
501 GL_CLAMP_TO_EDGE); | 548 GL_CLAMP_TO_EDGE); |
502 gles2_if_->TexParameterf( | 549 gles2_if_->TexParameterf( |
503 context_->pp_resource(), GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, | 550 context_->pp_resource(), texture_target, GL_TEXTURE_WRAP_T, |
504 GL_CLAMP_TO_EDGE); | 551 GL_CLAMP_TO_EDGE); |
505 | 552 |
506 gles2_if_->TexImage2D( | 553 if (texture_target == GL_TEXTURE_2D) { |
507 context_->pp_resource(), GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, | 554 gles2_if_->TexImage2D( |
508 GL_RGBA, GL_UNSIGNED_BYTE, NULL); | 555 context_->pp_resource(), texture_target, 0, GL_RGBA, width, height, 0, |
| 556 GL_RGBA, GL_UNSIGNED_BYTE, NULL); |
| 557 } |
509 assertNoGLError(); | 558 assertNoGLError(); |
510 return texture_id; | 559 return texture_id; |
511 } | 560 } |
512 | 561 |
513 void VideoDecodeDemoInstance::DeleteTexture(GLuint id) { | 562 void VideoDecodeDemoInstance::DeleteTexture(GLuint id) { |
514 gles2_if_->DeleteTextures(context_->pp_resource(), 1, &id); | 563 gles2_if_->DeleteTextures(context_->pp_resource(), 1, &id); |
515 } | 564 } |
516 | 565 |
517 void VideoDecodeDemoInstance::CreateGLObjects() { | 566 void VideoDecodeDemoInstance::CreateGLObjects() { |
518 // Code and constants for shader. | 567 // Code and constants for shader. |
519 static const char kVertexShader[] = | 568 static const char kVertexShader[] = |
520 "varying vec2 v_texCoord; \n" | 569 "varying vec2 v_texCoord; \n" |
521 "attribute vec4 a_position; \n" | 570 "attribute vec4 a_position; \n" |
522 "attribute vec2 a_texCoord; \n" | 571 "attribute vec2 a_texCoord; \n" |
| 572 "uniform vec2 v_scale; \n" |
523 "void main() \n" | 573 "void main() \n" |
524 "{ \n" | 574 "{ \n" |
525 " v_texCoord = a_texCoord; \n" | 575 " v_texCoord = v_scale * a_texCoord; \n" |
526 " gl_Position = a_position; \n" | 576 " gl_Position = a_position; \n" |
527 "}"; | 577 "}"; |
528 | 578 |
529 static const char kFragmentShader[] = | 579 static const char kFragmentShader2D[] = |
530 "precision mediump float; \n" | 580 "precision mediump float; \n" |
531 "varying vec2 v_texCoord; \n" | 581 "varying vec2 v_texCoord; \n" |
532 "uniform sampler2D s_texture; \n" | 582 "uniform sampler2D s_texture; \n" |
533 "void main() \n" | 583 "void main() \n" |
534 "{" | 584 "{" |
535 " gl_FragColor = texture2D(s_texture, v_texCoord); \n" | 585 " gl_FragColor = texture2D(s_texture, v_texCoord); \n" |
536 "}"; | 586 "}"; |
537 | 587 |
538 // Create shader program. | 588 static const char kFragmentShaderRectangle[] = |
539 GLuint program = gles2_if_->CreateProgram(context_->pp_resource()); | 589 "#extension GL_ARB_texture_rectangle : require\n" |
540 CreateShader(program, GL_VERTEX_SHADER, kVertexShader, sizeof(kVertexShader)); | 590 "precision mediump float; \n" |
541 CreateShader( | 591 "varying vec2 v_texCoord; \n" |
542 program, GL_FRAGMENT_SHADER, kFragmentShader, sizeof(kFragmentShader)); | 592 "uniform sampler2DRect s_texture; \n" |
543 gles2_if_->LinkProgram(context_->pp_resource(), program); | 593 "void main() \n" |
544 gles2_if_->UseProgram(context_->pp_resource(), program); | 594 "{" |
545 gles2_if_->DeleteProgram(context_->pp_resource(), program); | 595 " gl_FragColor = texture2DRect(s_texture, v_texCoord).rgba; \n" |
546 gles2_if_->Uniform1i( | 596 "}"; |
547 context_->pp_resource(), | |
548 gles2_if_->GetUniformLocation( | |
549 context_->pp_resource(), program, "s_texture"), 0); | |
550 assertNoGLError(); | |
551 | 597 |
552 // Assign vertex positions and texture coordinates to buffers for use in | 598 // Assign vertex positions and texture coordinates to buffers for use in |
553 // shader program. | 599 // shader program. |
554 static const float kVertices[] = { | 600 static const float kVertices[] = { |
555 -1, 1, -1, -1, 1, 1, 1, -1, // Position coordinates. | 601 -1, 1, -1, -1, 1, 1, 1, -1, // Position coordinates. |
556 0, 1, 0, 0, 1, 1, 1, 0, // Texture coordinates. | 602 0, 1, 0, 0, 1, 1, 1, 0, // Texture coordinates. |
557 }; | 603 }; |
558 | 604 |
559 GLuint buffer; | 605 GLuint buffer; |
560 gles2_if_->GenBuffers(context_->pp_resource(), 1, &buffer); | 606 gles2_if_->GenBuffers(context_->pp_resource(), 1, &buffer); |
561 gles2_if_->BindBuffer(context_->pp_resource(), GL_ARRAY_BUFFER, buffer); | 607 gles2_if_->BindBuffer(context_->pp_resource(), GL_ARRAY_BUFFER, buffer); |
| 608 |
562 gles2_if_->BufferData(context_->pp_resource(), GL_ARRAY_BUFFER, | 609 gles2_if_->BufferData(context_->pp_resource(), GL_ARRAY_BUFFER, |
563 sizeof(kVertices), kVertices, GL_STATIC_DRAW); | 610 sizeof(kVertices), kVertices, GL_STATIC_DRAW); |
564 assertNoGLError(); | 611 assertNoGLError(); |
| 612 |
| 613 shader_2d_ = CreateProgram(kVertexShader, kFragmentShader2D); |
| 614 shader_rectangle_arb_ = |
| 615 CreateProgram(kVertexShader, kFragmentShaderRectangle); |
| 616 } |
| 617 |
| 618 Shader VideoDecodeDemoInstance::CreateProgram(const char* vertex_shader, |
| 619 const char* fragment_shader) { |
| 620 Shader shader; |
| 621 |
| 622 // Create shader program. |
| 623 shader.program = gles2_if_->CreateProgram(context_->pp_resource()); |
| 624 CreateShader(shader.program, GL_VERTEX_SHADER, vertex_shader, |
| 625 strlen(vertex_shader)); |
| 626 CreateShader(shader.program, GL_FRAGMENT_SHADER, fragment_shader, |
| 627 strlen(fragment_shader)); |
| 628 gles2_if_->LinkProgram(context_->pp_resource(), shader.program); |
| 629 gles2_if_->UseProgram(context_->pp_resource(), shader.program); |
| 630 gles2_if_->Uniform1i( |
| 631 context_->pp_resource(), |
| 632 gles2_if_->GetUniformLocation( |
| 633 context_->pp_resource(), shader.program, "s_texture"), 0); |
| 634 assertNoGLError(); |
| 635 |
| 636 shader.texcoord_scale_location = gles2_if_->GetUniformLocation( |
| 637 context_->pp_resource(), shader.program, "v_scale"); |
| 638 |
565 GLint pos_location = gles2_if_->GetAttribLocation( | 639 GLint pos_location = gles2_if_->GetAttribLocation( |
566 context_->pp_resource(), program, "a_position"); | 640 context_->pp_resource(), shader.program, "a_position"); |
567 GLint tc_location = gles2_if_->GetAttribLocation( | 641 GLint tc_location = gles2_if_->GetAttribLocation( |
568 context_->pp_resource(), program, "a_texCoord"); | 642 context_->pp_resource(), shader.program, "a_texCoord"); |
569 assertNoGLError(); | 643 assertNoGLError(); |
| 644 |
570 gles2_if_->EnableVertexAttribArray(context_->pp_resource(), pos_location); | 645 gles2_if_->EnableVertexAttribArray(context_->pp_resource(), pos_location); |
571 gles2_if_->VertexAttribPointer(context_->pp_resource(), pos_location, 2, | 646 gles2_if_->VertexAttribPointer(context_->pp_resource(), pos_location, 2, |
572 GL_FLOAT, GL_FALSE, 0, 0); | 647 GL_FLOAT, GL_FALSE, 0, 0); |
573 gles2_if_->EnableVertexAttribArray(context_->pp_resource(), tc_location); | 648 gles2_if_->EnableVertexAttribArray(context_->pp_resource(), tc_location); |
574 gles2_if_->VertexAttribPointer( | 649 gles2_if_->VertexAttribPointer( |
575 context_->pp_resource(), tc_location, 2, GL_FLOAT, GL_FALSE, 0, | 650 context_->pp_resource(), tc_location, 2, GL_FLOAT, GL_FALSE, 0, |
576 static_cast<float*>(0) + 8); // Skip position coordinates. | 651 static_cast<float*>(0) + 8); // Skip position coordinates. |
| 652 |
| 653 gles2_if_->UseProgram(context_->pp_resource(), 0); |
577 assertNoGLError(); | 654 assertNoGLError(); |
| 655 return shader; |
578 } | 656 } |
579 | 657 |
580 void VideoDecodeDemoInstance::CreateShader( | 658 void VideoDecodeDemoInstance::CreateShader( |
581 GLuint program, GLenum type, const char* source, int size) { | 659 GLuint program, GLenum type, const char* source, int size) { |
582 GLuint shader = gles2_if_->CreateShader(context_->pp_resource(), type); | 660 GLuint shader = gles2_if_->CreateShader(context_->pp_resource(), type); |
583 gles2_if_->ShaderSource(context_->pp_resource(), shader, 1, &source, &size); | 661 gles2_if_->ShaderSource(context_->pp_resource(), shader, 1, &source, &size); |
584 gles2_if_->CompileShader(context_->pp_resource(), shader); | 662 gles2_if_->CompileShader(context_->pp_resource(), shader); |
585 gles2_if_->AttachShader(context_->pp_resource(), program, shader); | 663 gles2_if_->AttachShader(context_->pp_resource(), program, shader); |
586 gles2_if_->DeleteShader(context_->pp_resource(), shader); | 664 gles2_if_->DeleteShader(context_->pp_resource(), shader); |
587 } | 665 } |
588 } // anonymous namespace | 666 } // anonymous namespace |
589 | 667 |
590 namespace pp { | 668 namespace pp { |
591 // Factory function for your specialization of the Module object. | 669 // Factory function for your specialization of the Module object. |
592 Module* CreateModule() { | 670 Module* CreateModule() { |
593 return new VideoDecodeDemoModule(); | 671 return new VideoDecodeDemoModule(); |
594 } | 672 } |
595 } // namespace pp | 673 } // namespace pp |
OLD | NEW |