| 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 |