Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2011 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 "ppapi/c/dev/ppb_opengles_dev.h" | 7 #include "ppapi/c/dev/ppb_opengles_dev.h" |
| 8 #include "ppapi/c/pp_errors.h" | 8 #include "ppapi/c/pp_errors.h" |
| 9 #include "ppapi/cpp/dev/context_3d_dev.h" | 9 #include "ppapi/cpp/dev/context_3d_dev.h" |
| 10 #include "ppapi/cpp/dev/graphics_3d_client_dev.h" | 10 #include "ppapi/cpp/dev/graphics_3d_client_dev.h" |
| (...skipping 15 matching lines...) Expand all Loading... | |
| 26 | 26 |
| 27 namespace { | 27 namespace { |
| 28 | 28 |
| 29 class GLES2DemoInstance : public pp::Instance, public pp::Graphics3DClient_Dev, | 29 class GLES2DemoInstance : public pp::Instance, public pp::Graphics3DClient_Dev, |
| 30 public pp::VideoDecoderClient_Dev { | 30 public pp::VideoDecoderClient_Dev { |
| 31 public: | 31 public: |
| 32 GLES2DemoInstance(PP_Instance instance, pp::Module* module); | 32 GLES2DemoInstance(PP_Instance instance, pp::Module* module); |
| 33 virtual ~GLES2DemoInstance(); | 33 virtual ~GLES2DemoInstance(); |
| 34 | 34 |
| 35 // pp::Instance implementation (see PPP_Instance). | 35 // pp::Instance implementation (see PPP_Instance). |
| 36 virtual void DidChangeView(const pp::Rect& position_ignored, | 36 virtual void DidChangeView(const pp::Rect& position, |
| 37 const pp::Rect& clip); | 37 const pp::Rect& clip_ignored); |
| 38 | 38 |
| 39 // pp::Graphics3DClient_Dev implementation. | 39 // pp::Graphics3DClient_Dev implementation. |
| 40 virtual void Graphics3DContextLost() { | 40 virtual void Graphics3DContextLost() { |
| 41 // TODO(vrk/fischman): Properly reset after a lost graphics context. | 41 // TODO(vrk/fischman): Properly reset after a lost graphics context. In |
| 42 // particular need to delete context_ & surface_ and re-create textures. | |
| 43 // Probably have to recreate the decoder from scratch, because old textures | |
| 44 // can still be outstanding in the decoder! | |
| 42 assert(!"Unexpectedly lost graphics context"); | 45 assert(!"Unexpectedly lost graphics context"); |
| 43 } | 46 } |
| 44 | 47 |
| 45 // pp::VideoDecoderClient_Dev implementation. | 48 // pp::VideoDecoderClient_Dev implementation. |
| 46 virtual void ProvidePictureBuffers( | 49 virtual void ProvidePictureBuffers( |
| 47 pp::VideoDecoder_Dev decoder, uint32_t req_num_of_bufs, | 50 pp::VideoDecoder_Dev decoder, uint32_t req_num_of_bufs, |
| 48 PP_Size dimensions, PP_PictureBufferType_Dev type); | 51 PP_Size dimensions, PP_PictureBufferType_Dev type); |
| 49 virtual void DismissPictureBuffer( | 52 virtual void DismissPictureBuffer( |
| 50 pp::VideoDecoder_Dev decoder, int32_t picture_buffer_id); | 53 pp::VideoDecoder_Dev decoder, int32_t picture_buffer_id); |
| 51 virtual void PictureReady( | 54 virtual void PictureReady( |
| 52 pp::VideoDecoder_Dev decoder, const PP_Picture_Dev& picture); | 55 pp::VideoDecoder_Dev decoder, const PP_Picture_Dev& picture); |
| 53 virtual void EndOfStream(pp::VideoDecoder_Dev decoder); | 56 virtual void EndOfStream(pp::VideoDecoder_Dev decoder); |
| 54 virtual void NotifyError( | 57 virtual void NotifyError( |
| 55 pp::VideoDecoder_Dev decoder, PP_VideoDecodeError_Dev error); | 58 pp::VideoDecoder_Dev decoder, PP_VideoDecodeError_Dev error); |
| 56 | 59 |
| 57 private: | 60 private: |
| 58 // Helper struct that stores data used by the shader program. | 61 // Helper struct that stores data used by the shader program. |
| 59 struct ShaderInfo { | 62 struct ShaderInfo { |
| 60 GLint pos_location; | 63 GLint pos_location; |
| 61 GLint tc_location; | 64 GLint tc_location; |
| 62 GLint tex_location; | 65 GLint tex_location; |
| 63 GLuint vertex_buffers[2]; | 66 GLuint vertex_buffers[2]; |
| 64 }; | 67 }; |
| 65 | 68 |
| 69 // Serialize PPB_Video_Decoder_Dev operations w.r.t. GPU command buffer. | |
| 70 // TODO(fischman): figure out how much of this is actually necessary. | |
| 71 // Probably any necessary serialization ought to be happening in the | |
| 72 // PPAPI implementation, not in the plugin! | |
| 73 void FinishGL() { | |
| 74 gles2_if_->Finish(context_->pp_resource()); | |
|
scherkus (not reviewing)
2011/06/21 01:17:18
wow yeah that's a lot of manual FinishGL-ing :\
| |
| 75 } | |
| 76 | |
| 66 // Initialize Video Decoder. | 77 // Initialize Video Decoder. |
| 67 void InitializeDecoder(); | 78 void InitializeDecoder(); |
| 68 | 79 |
| 69 // Callbacks passed into pp:VideoDecoder_Dev functions. | 80 // Callbacks passed into pp:VideoDecoder_Dev functions. |
| 70 void DecoderInitDone(int32_t result); | 81 void DecoderInitDone(int32_t result); |
| 71 void DecoderBitstreamDone(int32_t result, int bitstream_buffer_id); | 82 void DecoderBitstreamDone(int32_t result, int bitstream_buffer_id); |
| 72 void DecoderFlushDone(int32_t result); | 83 void DecoderFlushDone(int32_t result); |
| 73 void DecoderAbortDone(int32_t result); | 84 void DecoderAbortDone(int32_t result); |
| 74 | 85 |
| 75 // Decode helpers. | 86 // Decode helpers. |
| 76 void DecodeNextNALU(); | 87 void DecodeNextNALU(); |
| 77 void GetNextNALUBoundary(size_t start_pos, size_t* end_pos); | 88 void GetNextNALUBoundary(size_t start_pos, size_t* end_pos); |
| 78 void Render(const PP_GLESBuffer_Dev& buffer); | 89 void Render(const PP_GLESBuffer_Dev& buffer); |
| 79 | 90 |
| 80 // GL-related functions. | 91 // GL-related functions. |
| 81 void InitGL(int width, int height); | 92 void InitGL(); |
| 82 GLuint CreateTexture(int32_t width, int32_t height); | 93 GLuint CreateTexture(int32_t width, int32_t height); |
| 83 void CreateGLObjects(); | 94 void CreateGLObjects(); |
| 84 void CreateShader(GLuint program, GLenum type, const char* source, int size); | 95 void CreateShader(GLuint program, GLenum type, const char* source, int size); |
| 85 void DeleteTexture(GLuint id); | 96 void DeleteTexture(GLuint id); |
| 86 void PaintFinished(int32_t result, int picture_buffer_id); | 97 void PaintFinished(int32_t result, int picture_buffer_id); |
| 87 | 98 |
| 88 // Assert |context_| isn't holding any GL Errors. | 99 // Assert |context_| isn't holding any GL Errors. |
| 89 void assertNoGLError() { | 100 void assertNoGLError() { |
| 90 assert(!gles2_if_->GetError(context_->pp_resource())); | 101 assert(!gles2_if_->GetError(context_->pp_resource())); |
| 91 } | 102 } |
| 92 | 103 |
| 104 pp::Size position_size_; | |
| 93 ShaderInfo program_data_; | 105 ShaderInfo program_data_; |
| 94 int next_picture_buffer_id_; | 106 int next_picture_buffer_id_; |
| 95 int next_bitstream_buffer_id_; | 107 int next_bitstream_buffer_id_; |
| 96 bool is_painting_; | 108 bool is_painting_; |
| 97 pp::CompletionCallbackFactory<GLES2DemoInstance> callback_factory_; | 109 pp::CompletionCallbackFactory<GLES2DemoInstance> callback_factory_; |
| 98 size_t encoded_data_next_pos_to_decode_; | 110 size_t encoded_data_next_pos_to_decode_; |
| 99 | 111 |
| 100 // Map of texture buffers indexed by buffer id. | 112 // Map of texture buffers indexed by buffer id. |
| 101 typedef std::map<int, PP_GLESBuffer_Dev> PictureBufferMap; | 113 typedef std::map<int, PP_GLESBuffer_Dev> PictureBufferMap; |
| 102 PictureBufferMap buffers_by_id_; | 114 PictureBufferMap buffers_by_id_; |
| (...skipping 25 matching lines...) Expand all Loading... | |
| 128 assert(gles2_if_); | 140 assert(gles2_if_); |
| 129 } | 141 } |
| 130 | 142 |
| 131 GLES2DemoInstance::~GLES2DemoInstance() { | 143 GLES2DemoInstance::~GLES2DemoInstance() { |
| 132 delete video_decoder_; | 144 delete video_decoder_; |
| 133 delete surface_; | 145 delete surface_; |
| 134 delete context_; | 146 delete context_; |
| 135 } | 147 } |
| 136 | 148 |
| 137 void GLES2DemoInstance::DidChangeView( | 149 void GLES2DemoInstance::DidChangeView( |
| 138 const pp::Rect& position_ignored, const pp::Rect& clip) { | 150 const pp::Rect& position, const pp::Rect& clip_ignored) { |
| 139 if (clip.width() == 0 || clip.height() == 0) | 151 if (position.width() == 0 || position.height() == 0) |
| 140 return; | 152 return; |
| 153 if (position_size_.width()) { | |
| 154 assert(position.size() == position_size_); | |
| 155 return; | |
| 156 } | |
| 157 position_size_ = position.size(); | |
| 141 | 158 |
| 142 // Initialize graphics. | 159 // Initialize graphics. |
| 143 InitGL(clip.width(), clip.height()); | 160 InitGL(); |
| 144 InitializeDecoder(); | 161 InitializeDecoder(); |
| 145 } | 162 } |
| 146 | 163 |
| 147 void GLES2DemoInstance::InitializeDecoder() { | 164 void GLES2DemoInstance::InitializeDecoder() { |
| 148 if (video_decoder_) | 165 if (video_decoder_) |
| 149 return; | 166 return; |
| 150 video_decoder_ = new pp::VideoDecoder_Dev(*this); | 167 video_decoder_ = new pp::VideoDecoder_Dev(*this); |
| 151 | 168 |
| 152 PP_VideoConfigElement configs = PP_VIDEOATTR_DICTIONARY_TERMINATOR; | 169 PP_VideoConfigElement configs = PP_VIDEOATTR_DICTIONARY_TERMINATOR; |
| 153 pp::CompletionCallback cb = | 170 pp::CompletionCallback cb = |
| (...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 229 std::vector<PP_GLESBuffer_Dev> buffers; | 246 std::vector<PP_GLESBuffer_Dev> buffers; |
| 230 for (uint32_t i = 0; i < req_num_of_bufs; i++) { | 247 for (uint32_t i = 0; i < req_num_of_bufs; i++) { |
| 231 PP_GLESBuffer_Dev buffer; | 248 PP_GLESBuffer_Dev buffer; |
| 232 buffer.texture_id = CreateTexture(dimensions.width, dimensions.height); | 249 buffer.texture_id = CreateTexture(dimensions.width, dimensions.height); |
| 233 int id = ++next_picture_buffer_id_; | 250 int id = ++next_picture_buffer_id_; |
| 234 buffer.info.id= id; | 251 buffer.info.id= id; |
| 235 buffers.push_back(buffer); | 252 buffers.push_back(buffer); |
| 236 bool result = buffers_by_id_.insert(std::make_pair(id, buffer)).second; | 253 bool result = buffers_by_id_.insert(std::make_pair(id, buffer)).second; |
| 237 assert(result); | 254 assert(result); |
| 238 } | 255 } |
| 256 FinishGL(); | |
| 239 video_decoder_->AssignGLESBuffers(buffers); | 257 video_decoder_->AssignGLESBuffers(buffers); |
| 240 } | 258 } |
| 241 | 259 |
| 242 void GLES2DemoInstance::DismissPictureBuffer( | 260 void GLES2DemoInstance::DismissPictureBuffer( |
| 243 pp::VideoDecoder_Dev decoder, int32_t picture_buffer_id) { | 261 pp::VideoDecoder_Dev decoder, int32_t picture_buffer_id) { |
| 244 PictureBufferMap::iterator it = buffers_by_id_.find(picture_buffer_id); | 262 PictureBufferMap::iterator it = buffers_by_id_.find(picture_buffer_id); |
| 245 assert(it != buffers_by_id_.end()); | 263 assert(it != buffers_by_id_.end()); |
| 246 DeleteTexture(it->second.texture_id); | 264 DeleteTexture(it->second.texture_id); |
| 247 buffers_by_id_.erase(it); | 265 buffers_by_id_.erase(it); |
| 266 | |
| 267 FinishGL(); | |
| 248 } | 268 } |
| 249 | 269 |
| 250 void GLES2DemoInstance::PictureReady( | 270 void GLES2DemoInstance::PictureReady( |
| 251 pp::VideoDecoder_Dev decoder, const PP_Picture_Dev& picture) { | 271 pp::VideoDecoder_Dev decoder, const PP_Picture_Dev& picture) { |
| 252 PictureBufferMap::iterator it = | 272 PictureBufferMap::iterator it = |
| 253 buffers_by_id_.find(picture.picture_buffer_id); | 273 buffers_by_id_.find(picture.picture_buffer_id); |
| 254 assert(it != buffers_by_id_.end()); | 274 assert(it != buffers_by_id_.end()); |
| 255 Render(it->second); | 275 Render(it->second); |
| 256 } | 276 } |
| 257 | 277 |
| 258 void GLES2DemoInstance::EndOfStream(pp::VideoDecoder_Dev decoder) { | 278 void GLES2DemoInstance::EndOfStream(pp::VideoDecoder_Dev decoder) { |
| 259 } | 279 } |
| 260 | 280 |
| 261 void GLES2DemoInstance::NotifyError( | 281 void GLES2DemoInstance::NotifyError( |
| 262 pp::VideoDecoder_Dev decoder, PP_VideoDecodeError_Dev error) { | 282 pp::VideoDecoder_Dev decoder, PP_VideoDecodeError_Dev error) { |
| 263 } | 283 } |
| 264 | 284 |
| 265 // This object is the global object representing this plugin library as long | 285 // This object is the global object representing this plugin library as long |
| 266 // as it is loaded. | 286 // as it is loaded. |
| 267 class GLES2DemoModule : public pp::Module { | 287 class GLES2DemoModule : public pp::Module { |
| 268 public: | 288 public: |
| 269 GLES2DemoModule() : pp::Module() {} | 289 GLES2DemoModule() : pp::Module() {} |
| 270 virtual ~GLES2DemoModule() {} | 290 virtual ~GLES2DemoModule() {} |
| 271 | 291 |
| 272 virtual pp::Instance* CreateInstance(PP_Instance instance) { | 292 virtual pp::Instance* CreateInstance(PP_Instance instance) { |
| 273 return new GLES2DemoInstance(instance, this); | 293 return new GLES2DemoInstance(instance, this); |
| 274 } | 294 } |
| 275 }; | 295 }; |
| 276 | 296 |
| 277 void GLES2DemoInstance::InitGL(int width, int height) { | 297 void GLES2DemoInstance::InitGL() { |
| 278 assert(width && height); | 298 assert(position_size_.width() && position_size_.height()); |
| 279 is_painting_ = false; | 299 is_painting_ = false; |
| 280 | 300 |
| 281 if (context_) | 301 assert(!context_ && !surface_); |
| 282 delete(context_); | |
| 283 context_ = new pp::Context3D_Dev(*this, 0, pp::Context3D_Dev(), NULL); | 302 context_ = new pp::Context3D_Dev(*this, 0, pp::Context3D_Dev(), NULL); |
| 284 assert(!context_->is_null()); | 303 assert(!context_->is_null()); |
| 285 | 304 |
| 286 int32_t surface_attributes[] = { | 305 int32_t surface_attributes[] = { |
| 287 PP_GRAPHICS3DATTRIB_WIDTH, width, | 306 PP_GRAPHICS3DATTRIB_WIDTH, position_size_.width(), |
| 288 PP_GRAPHICS3DATTRIB_HEIGHT, height, | 307 PP_GRAPHICS3DATTRIB_HEIGHT, position_size_.height(), |
| 289 PP_GRAPHICS3DATTRIB_NONE | 308 PP_GRAPHICS3DATTRIB_NONE |
| 290 }; | 309 }; |
| 291 if (surface_) | |
| 292 delete(surface_); | |
| 293 surface_ = new pp::Surface3D_Dev(*this, 0, surface_attributes); | 310 surface_ = new pp::Surface3D_Dev(*this, 0, surface_attributes); |
| 294 assert(!surface_->is_null()); | 311 assert(!surface_->is_null()); |
| 295 | 312 |
| 296 int32_t bind_error = context_->BindSurfaces(*surface_, *surface_); | 313 int32_t bind_error = context_->BindSurfaces(*surface_, *surface_); |
| 297 assert(!bind_error); | 314 assert(!bind_error); |
| 298 | 315 |
| 299 // Set viewport window size and clear color bit. | 316 // Set viewport window size and clear color bit. |
| 300 gles2_if_->Clear(context_->pp_resource(), GL_COLOR_BUFFER_BIT); | 317 gles2_if_->Clear(context_->pp_resource(), GL_COLOR_BUFFER_BIT); |
| 301 gles2_if_->Viewport(context_->pp_resource(), 0, 0, width, height); | 318 gles2_if_->Viewport(context_->pp_resource(), 0, 0, |
| 319 position_size_.width(), position_size_.height()); | |
| 302 | 320 |
| 303 bool success = BindGraphics(*surface_); | 321 bool success = BindGraphics(*surface_); |
| 304 assert(success); | 322 assert(success); |
| 305 assertNoGLError(); | 323 assertNoGLError(); |
| 306 | 324 |
| 307 CreateGLObjects(); | 325 CreateGLObjects(); |
| 326 | |
| 327 FinishGL(); | |
| 308 } | 328 } |
| 309 | 329 |
| 310 void GLES2DemoInstance::Render(const PP_GLESBuffer_Dev& buffer) { | 330 void GLES2DemoInstance::Render(const PP_GLESBuffer_Dev& buffer) { |
| 311 if (is_painting_) { | 331 if (is_painting_) { |
| 312 // We are dropping frames if we don't render fast enough - | 332 // We are dropping frames if we don't render fast enough - |
| 313 // that is why sometimes the last frame rendered is < 249. | 333 // that is why sometimes the last frame rendered is < 249. |
| 314 if (video_decoder_) | 334 if (video_decoder_) { |
| 335 FinishGL(); | |
| 315 video_decoder_->ReusePictureBuffer(buffer.info.id); | 336 video_decoder_->ReusePictureBuffer(buffer.info.id); |
| 337 } | |
| 316 return; | 338 return; |
| 317 } | 339 } |
| 318 is_painting_ = true; | 340 is_painting_ = true; |
| 319 gles2_if_->ActiveTexture(context_->pp_resource(), GL_TEXTURE0); | 341 gles2_if_->ActiveTexture(context_->pp_resource(), GL_TEXTURE0); |
| 320 gles2_if_->BindTexture( | 342 gles2_if_->BindTexture( |
| 321 context_->pp_resource(), GL_TEXTURE_2D, buffer.texture_id); | 343 context_->pp_resource(), GL_TEXTURE_2D, buffer.texture_id); |
| 322 gles2_if_->Uniform1i(context_->pp_resource(), program_data_.tex_location, 0); | 344 gles2_if_->Uniform1i(context_->pp_resource(), program_data_.tex_location, 0); |
| 323 gles2_if_->DrawArrays(context_->pp_resource(), GL_TRIANGLE_STRIP, 0, 4); | 345 gles2_if_->DrawArrays(context_->pp_resource(), GL_TRIANGLE_STRIP, 0, 4); |
| 324 pp::CompletionCallback cb = | 346 pp::CompletionCallback cb = |
| 325 callback_factory_.NewCallback( | 347 callback_factory_.NewCallback( |
| 326 &GLES2DemoInstance::PaintFinished, buffer.info.id); | 348 &GLES2DemoInstance::PaintFinished, buffer.info.id); |
| 327 int32_t error = surface_->SwapBuffers(cb); | 349 int32_t error = surface_->SwapBuffers(cb); |
| 328 assert(error == PP_ERROR_WOULDBLOCK); | 350 assert(error == PP_ERROR_WOULDBLOCK); |
| 329 assertNoGLError(); | 351 assertNoGLError(); |
| 330 } | 352 } |
| 331 | 353 |
| 332 void GLES2DemoInstance::PaintFinished(int32_t result, int picture_buffer_id) { | 354 void GLES2DemoInstance::PaintFinished(int32_t result, int picture_buffer_id) { |
| 333 is_painting_ = false; | 355 is_painting_ = false; |
| 356 FinishGL(); | |
| 334 if (video_decoder_) | 357 if (video_decoder_) |
| 335 video_decoder_->ReusePictureBuffer(picture_buffer_id); | 358 video_decoder_->ReusePictureBuffer(picture_buffer_id); |
| 336 } | 359 } |
| 337 | 360 |
| 338 GLuint GLES2DemoInstance::CreateTexture(int32_t width, int32_t height) { | 361 GLuint GLES2DemoInstance::CreateTexture(int32_t width, int32_t height) { |
| 339 GLuint texture_id; | 362 GLuint texture_id; |
| 340 gles2_if_->GenTextures(context_->pp_resource(), 1, &texture_id); | 363 gles2_if_->GenTextures(context_->pp_resource(), 1, &texture_id); |
| 341 assertNoGLError(); | 364 assertNoGLError(); |
| 342 // Assign parameters. | 365 // Assign parameters. |
| 343 gles2_if_->ActiveTexture(context_->pp_resource(), GL_TEXTURE0); | 366 gles2_if_->ActiveTexture(context_->pp_resource(), GL_TEXTURE0); |
| (...skipping 124 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 468 gles2_if_->DeleteShader(context_->pp_resource(), shader); | 491 gles2_if_->DeleteShader(context_->pp_resource(), shader); |
| 469 } | 492 } |
| 470 } // anonymous namespace | 493 } // anonymous namespace |
| 471 | 494 |
| 472 namespace pp { | 495 namespace pp { |
| 473 // Factory function for your specialization of the Module object. | 496 // Factory function for your specialization of the Module object. |
| 474 Module* CreateModule() { | 497 Module* CreateModule() { |
| 475 return new GLES2DemoModule(); | 498 return new GLES2DemoModule(); |
| 476 } | 499 } |
| 477 } // namespace pp | 500 } // namespace pp |
| OLD | NEW |