diff --git a/TODO b/TODO index e99523c4cf..26ad620f81 100644 --- a/TODO +++ b/TODO @@ -17,3 +17,4 @@ Official TODO Queue: -) Add Named Objects to frames and not to clips -) Support mozilla Out of process plugin mode - Waiting for multithreaded GTK support from mozilla -) Conditional scaling of FontGlyph based on version +-) Why std::istream catches our exeptions? diff --git a/plugin-dir/plugin.cpp b/plugin-dir/plugin.cpp index e4da3c6ebb..f3a8f288e9 100644 --- a/plugin-dir/plugin.cpp +++ b/plugin-dir/plugin.cpp @@ -268,6 +268,8 @@ nsPluginInstance::nsPluginInstance(NPP aInstance, int16_t argc, char** argn, cha sys->setOrigin(argv[i]); } } + m_sys.downloadManager=new NPDownloadManager(mInstance); + m_sys.addJob(&m_pt); } int nsPluginInstance::hexToInt(char c) @@ -286,6 +288,8 @@ nsPluginInstance::~nsPluginInstance() { //Shutdown the system //cerr << "instance dying" << endl; + swf_buf.destroy(); + m_pt.stop(); m_sys.setShutdownFlag(); m_sys.wait(); if(m_rt) @@ -399,8 +403,6 @@ NPError nsPluginInstance::SetWindow(NPWindow* aWindow) sys=NULL; m_sys.inputThread=m_it; m_sys.renderThread=m_rt; - m_sys.downloadManager=new NPDownloadManager(mInstance); - m_sys.addJob(&m_pt); } //draw(); return TRUE; diff --git a/streams.cpp b/streams.cpp index 4e6a753fd8..0d5b8d051d 100644 --- a/streams.cpp +++ b/streams.cpp @@ -26,7 +26,7 @@ using namespace std; -sync_stream::sync_stream():head(0),tail(0),wait_notfull(false),wait_notempty(false),buf_size(1024*1024) +sync_stream::sync_stream():head(0),tail(0),wait_notfull(false),wait_notempty(false),buf_size(1024*1024),failed(false) { buffer=new char[buf_size]; sem_init(&mutex,0,1); @@ -41,6 +41,13 @@ sync_stream::~sync_stream() sem_destroy(¬empty); } +void sync_stream::destroy() +{ + failed=true; + sem_post(¬full); + sem_post(¬empty); +} + int sync_stream::provideBuffer(int limit) { sem_wait(&mutex); @@ -49,6 +56,8 @@ int sync_stream::provideBuffer(int limit) wait_notempty=true; sem_post(&mutex); sem_wait(¬empty); + if(failed) + return 0; } int available=(tail-head+buf_size)%buf_size; @@ -82,6 +91,8 @@ uint32_t sync_stream::write(char* buf, int len) wait_notfull=true; sem_post(&mutex); sem_wait(¬full); + if(failed) + return 0; } if((head-tail+buf_size-1)%buf_size> Signature[0] >> Signature[1] >> Signature[2]; @@ -72,7 +72,7 @@ SWF_HEADER::SWF_HEADER(istream& in) else { LOG(LOG_NO_INFO,"No SWF file signature found"); - abort(); + return; } pt->version=Version; in >> FrameSize >> FrameRate >> FrameCount; @@ -85,9 +85,10 @@ SWF_HEADER::SWF_HEADER(istream& in) sys->setRenderRate(frameRate); pt->root->version=Version; pt->root->fileLenght=FileLength; + valid=true; } -RootMovieClip::RootMovieClip(LoaderInfo* li, bool isSys):initialized(false),frameRate(0),toBind(false) +RootMovieClip::RootMovieClip(LoaderInfo* li, bool isSys):initialized(false),parsingIsFailed(false),frameRate(0),toBind(false) { root=this; sem_init(&mutex,0,1); @@ -116,6 +117,15 @@ RootMovieClip::~RootMovieClip() sem_destroy(&sem_valid_size); } +void RootMovieClip::parsingFailed() +{ + //The parsing is failed, we have no change to be ever valid + parsingIsFailed=true; + sem_post(&new_frame); + sem_post(&sem_valid_size); + sem_post(&sem_valid_rate); +} + void RootMovieClip::bindToName(const tiny_string& n) { assert(toBind==false); @@ -404,6 +414,8 @@ void ParseThread::execute() try { SWF_HEADER h(f); + if(!h.valid) + throw ParseException("Not an SWF file"); root->setFrameSize(h.getFrameSize()); root->setFrameCount(h.FrameCount); @@ -455,6 +467,8 @@ void ParseThread::execute() } catch(LightsparkException& e) { + LOG(LOG_ERROR,"Exception in ParseThread " << e.what()); + root->parsingFailed(); sys->setError(e.cause); } pt=NULL; @@ -464,8 +478,8 @@ void ParseThread::execute() void ParseThread::threadAbort() { - //TODO: implement - ::abort(); + //Tell the our RootMovieClip that the parsing is ending + root->parsingFailed(); } void ParseThread::wait() @@ -1484,6 +1498,8 @@ void RootMovieClip::Render() sem_post(&sem_frames); sem_wait(&new_frame); + if(parsingIsFailed) + return; sem_wait(&sem_frames); } @@ -1549,6 +1565,7 @@ void RenderThread::commonGLInit(int width, int height, unsigned int t2[3]) glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_S,GL_CLAMP); glTexEnvf( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE ); + while(glGetError()!=GL_NO_ERROR); glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0); glBindTexture(GL_TEXTURE_2D,t2[1]); @@ -1582,6 +1599,11 @@ void RenderThread::commonGLInit(int width, int height, unsigned int t2[3]) if(status != GL_FRAMEBUFFER_COMPLETE) { LOG(LOG_ERROR,"Incomplete FBO status " << status << "... Aborting"); + while(err!=GL_NO_ERROR) + { + LOG(LOG_ERROR,"GL errors during initialization: " << err); + err=glGetError(); + } ::abort(); } } diff --git a/swf.h b/swf.h index 3951fd7308..cb8d84e698 100644 --- a/swf.h +++ b/swf.h @@ -71,7 +71,7 @@ class SWF_HEADER RECT FrameSize; UI16 FrameRate; UI16 FrameCount; -public: + bool valid; SWF_HEADER(std::istream& in); const RECT& getFrameSize(){ return FrameSize; } }; @@ -82,11 +82,12 @@ class RootMovieClip: public MovieClip, public ITickJob friend class ParseThread; protected: sem_t mutex; - //Semaphore to wait for new frames to be available - sem_t new_frame; bool initialized; tiny_string origin; private: + //Semaphore to wait for new frames to be available + sem_t new_frame; + bool parsingIsFailed; RGB Background; std::list < DictionaryTag* > dictionary; //frameSize and frameRate are valid only after the header has been parsed @@ -118,6 +119,7 @@ friend class ParseThread; void commitFrame(bool another); void revertFrame(); void Render(); + void parsingFailed(); bool getBounds(number_t& xmin, number_t& xmax, number_t& ymin, number_t& ymax) const; void bindToName(const tiny_string& n); void initialize();