# HG changeset patch # User Benjamin Golinvaux # Date 1566396990 -7200 # Node ID a7351ad549603819a519c201c25618d390351642 # Parent 118fc5c85d0706b2c28d17d9213cf34f58c49a90 Made IsContextLost automatically set the flag by checking with the emscripten WebGL wrapper + added a LOT of logging messages right before throwing ErrorCode_BadSequenceOfCalls exceptions + increased the http request timeouts from 60 to 600 sec (big datasets in some recent customer use cases) + added IsContext lost through the Viewport/Context layer (to make it reachable from external API) + the same for the underlying device context (for debug) diff -r 118fc5c85d07 -r a7351ad54960 Applications/Sdl/SdlOpenGLContext.cpp --- a/Applications/Sdl/SdlOpenGLContext.cpp Fri Aug 16 16:24:11 2019 +0200 +++ b/Applications/Sdl/SdlOpenGLContext.cpp Wed Aug 21 16:16:30 2019 +0200 @@ -86,12 +86,11 @@ } - bool SdlOpenGLContext::IsContextLost() const + bool SdlOpenGLContext::IsContextLost() { return contextLost_; } - - + void SdlOpenGLContext::SetLostContext() { contextLost_ = true; diff -r 118fc5c85d07 -r a7351ad54960 Applications/Sdl/SdlOpenGLContext.h --- a/Applications/Sdl/SdlOpenGLContext.h Fri Aug 16 16:24:11 2019 +0200 +++ b/Applications/Sdl/SdlOpenGLContext.h Wed Aug 21 16:16:30 2019 +0200 @@ -50,7 +50,7 @@ return window_; } - virtual bool IsContextLost() const ORTHANC_OVERRIDE; + virtual bool IsContextLost() ORTHANC_OVERRIDE; virtual void SetLostContext() ORTHANC_OVERRIDE; virtual void RestoreLostContext() ORTHANC_OVERRIDE; diff -r 118fc5c85d07 -r a7351ad54960 Framework/Loaders/LoaderStateMachine.cpp --- a/Framework/Loaders/LoaderStateMachine.cpp Fri Aug 16 16:24:11 2019 +0200 +++ b/Framework/Loaders/LoaderStateMachine.cpp Wed Aug 21 16:16:30 2019 +0200 @@ -67,6 +67,7 @@ { if (active_) { + LOG(ERROR) << "LoaderStateMachine::Start() called while active_ is true"; throw Orthanc::OrthancException(Orthanc::ErrorCode_BadSequenceOfCalls); } @@ -106,13 +107,12 @@ void LoaderStateMachine::HandleExceptionMessage(const OracleCommandExceptionMessage& message) { - LOG(ERROR) << "Error in the state machine, stopping all processing"; + LOG(ERROR) << "LoaderStateMachine::HandleExceptionMessage: error in the state machine, stopping all processing"; LOG(ERROR) << "Error: " << message.GetException().What() << " Details: " << message.GetException().GetDetails(); Clear(); } - template void LoaderStateMachine::HandleSuccessMessage(const T& message) { @@ -163,6 +163,7 @@ { if (active_) { + LOG(ERROR) << "LoaderStateMachine::SetSimultaneousDownloads called while active_ is true"; throw Orthanc::OrthancException(Orthanc::ErrorCode_BadSequenceOfCalls); } else if (count == 0) diff -r 118fc5c85d07 -r a7351ad54960 Framework/Loaders/OrthancMultiframeVolumeLoader.cpp --- a/Framework/Loaders/OrthancMultiframeVolumeLoader.cpp Fri Aug 16 16:24:11 2019 +0200 +++ b/Framework/Loaders/OrthancMultiframeVolumeLoader.cpp Wed Aug 21 16:16:30 2019 +0200 @@ -150,6 +150,7 @@ } else { + LOG(ERROR) << "OrthancMultiframeVolumeLoader::GetInstanceId(): (!IsActive())"; throw Orthanc::OrthancException(Orthanc::ErrorCode_BadSequenceOfCalls); } } diff -r 118fc5c85d07 -r a7351ad54960 Framework/Loaders/OrthancSeriesVolumeProgressiveLoader.cpp --- a/Framework/Loaders/OrthancSeriesVolumeProgressiveLoader.cpp Fri Aug 16 16:24:11 2019 +0200 +++ b/Framework/Loaders/OrthancSeriesVolumeProgressiveLoader.cpp Wed Aug 21 16:16:30 2019 +0200 @@ -140,6 +140,7 @@ { if (!HasGeometry()) { + LOG(ERROR) << "OrthancSeriesVolumeProgressiveLoader::SeriesGeometry::CheckSliceIndex(size_t index): (!HasGeometry())"; throw Orthanc::OrthancException(Orthanc::ErrorCode_BadSequenceOfCalls); } else if (index >= slices_.size()) @@ -204,6 +205,7 @@ { if (!HasGeometry()) { + LOG(ERROR) << "OrthancSeriesVolumeProgressiveLoader::SeriesGeometry::GetImageGeometry(): (!HasGeometry())"; throw Orthanc::OrthancException(Orthanc::ErrorCode_BadSequenceOfCalls); } else @@ -450,6 +452,7 @@ { if (active_) { + LOG(ERROR) << "OrthancSeriesVolumeProgressiveLoader::SetSimultaneousDownloads(): (active_)"; throw Orthanc::OrthancException(Orthanc::ErrorCode_BadSequenceOfCalls); } else if (count == 0) @@ -469,6 +472,7 @@ if (active_) { // LOG(TRACE) << "OrthancSeriesVolumeProgressiveLoader::LoadSeries NOT ACTIVE! --> ERROR"; + LOG(ERROR) << "OrthancSeriesVolumeProgressiveLoader::LoadSeries(const std::string& seriesId): (active_)"; throw Orthanc::OrthancException(Orthanc::ErrorCode_BadSequenceOfCalls); } else diff -r 118fc5c85d07 -r a7351ad54960 Framework/OpenGL/IOpenGLContext.h --- a/Framework/OpenGL/IOpenGLContext.h Fri Aug 16 16:24:11 2019 +0200 +++ b/Framework/OpenGL/IOpenGLContext.h Wed Aug 21 16:16:30 2019 +0200 @@ -34,7 +34,7 @@ { } - virtual bool IsContextLost() const = 0; + virtual bool IsContextLost() = 0; virtual void MakeCurrent() = 0; diff -r 118fc5c85d07 -r a7351ad54960 Framework/OpenGL/OpenGLShader.cpp --- a/Framework/OpenGL/OpenGLShader.cpp Fri Aug 16 16:24:11 2019 +0200 +++ b/Framework/OpenGL/OpenGLShader.cpp Wed Aug 21 16:16:30 2019 +0200 @@ -127,6 +127,7 @@ } else { + LOG(ERROR) << "OpenGLShader::Release(): (!isValid_)"; throw Orthanc::OrthancException(Orthanc::ErrorCode_BadSequenceOfCalls); } } diff -r 118fc5c85d07 -r a7351ad54960 Framework/OpenGL/WebAssemblyOpenGLContext.cpp --- a/Framework/OpenGL/WebAssemblyOpenGLContext.cpp Fri Aug 16 16:24:11 2019 +0200 +++ b/Framework/OpenGL/WebAssemblyOpenGLContext.cpp Wed Aug 21 16:16:30 2019 +0200 @@ -69,25 +69,48 @@ return reinterpret_cast(context_); } - bool IsContextLost() const - { + bool IsContextLost() + { + LOG(TRACE) << "IsContextLost() for context " << std::hex() << bool apiFlag = (emscripten_is_webgl_context_lost(context_) != 0); - bool ownFlag = isContextLost_; - if (ownFlag != apiFlag) - { - LOG(WARNING) << "Context loss, according to emscripten, is: " << apiFlag << " | while, according to internal state, is: " << ownFlag; - } - return ownFlag | apiFlag; - } - - void SetLostContext() + isContextLost_ = apiFlag; + return isContextLost_; + } + + void SetLostContext() { isContextLost_ = true; } ~PImpl() { - emscripten_webgl_destroy_context(context_); + try + { + EMSCRIPTEN_RESULT result = emscripten_webgl_destroy_context(context_); + if (result != EMSCRIPTEN_RESULT_SUCCESS) + { + LOG(ERROR) << "emscripten_webgl_destroy_context returned code " << result; + } + } + catch (const Orthanc::OrthancException& e) + { + if (e.HasDetails()) + { + LOG(ERROR) << "OrthancException in WebAssemblyOpenGLContext::~PImpl: " << e.What() << " Details: " << e.GetDetails(); + } + else + { + LOG(ERROR) << "OrthancException in WebAssemblyOpenGLContext::~PImpl: " << e.What(); + } + } + catch (const std::exception& e) + { + LOG(ERROR) << "std::exception in WebAssemblyOpenGLContext::~PImpl: " << e.what(); + } + catch (...) + { + LOG(ERROR) << "Unknown exception in WebAssemblyOpenGLContext::~PImpl"; + } } const std::string& GetCanvasIdentifier() const @@ -177,7 +200,50 @@ { } - bool WebAssemblyOpenGLContext::IsContextLost() const + //bool WebAssemblyOpenGLContext::TryRecreate() + //{ + // // LOG(ERROR) << "WebAssemblyOpenGLContext::TryRecreate() trying to recreate context"; + // try + // { + // std::string canvasId = GetCanvasIdentifier(); + // pimpl_.reset(new PImpl(canvasId)); + + // // no exception does not mean the context is fully + // // functional! Most probably, if we have >= than 16 + // // contexts, context wil remain lost for some time + // bool lost = IsContextLost(); + // if (lost) { + // // LOG(ERROR) << "WebAssemblyOpenGLContext::TryRecreate() context is still lost!"; + // return false; + // } else { + // return true; + // } + // } + // catch (const Orthanc::OrthancException& e) + // { + // if (e.HasDetails()) + // { + // LOG(ERROR) << "OrthancException in WebAssemblyOpenGLContext::TryRecreate: " << e.What() << " Details: " << e.GetDetails(); + // } + // else + // { + // LOG(ERROR) << "OrthancException in WebAssemblyOpenGLContext::TryRecreate: " << e.What(); + // } + // return false; + // } + // catch (const std::exception& e) + // { + // LOG(ERROR) << "std::exception in WebAssemblyOpenGLContext::TryRecreate: " << e.what(); + // return false; + // } + // catch (...) + // { + // LOG(ERROR) << "Unknown exception WebAssemblyOpenGLContext::in TryRecreate"; + // return false; + // } + //} + + bool WebAssemblyOpenGLContext::IsContextLost() { return pimpl_->IsContextLost(); } diff -r 118fc5c85d07 -r a7351ad54960 Framework/OpenGL/WebAssemblyOpenGLContext.h --- a/Framework/OpenGL/WebAssemblyOpenGLContext.h Fri Aug 16 16:24:11 2019 +0200 +++ b/Framework/OpenGL/WebAssemblyOpenGLContext.h Wed Aug 21 16:16:30 2019 +0200 @@ -56,10 +56,10 @@ public: WebAssemblyOpenGLContext(const std::string& canvas); - virtual bool IsContextLost() const ORTHANC_OVERRIDE; - - virtual void SetLostContext() ORTHANC_OVERRIDE; - virtual void RestoreLostContext() ORTHANC_OVERRIDE; + virtual bool IsContextLost() ORTHANC_OVERRIDE; + + virtual void SetLostContext() ORTHANC_OVERRIDE; + virtual void RestoreLostContext() ORTHANC_OVERRIDE; virtual void MakeCurrent() ORTHANC_OVERRIDE; @@ -71,6 +71,11 @@ virtual void* DebugGetInternalContext() const ORTHANC_OVERRIDE; + /** + Returns true if the underlying context has been successfully recreated + */ + //bool TryRecreate(); + void UpdateSize(); const std::string& GetCanvasIdentifier() const; diff -r 118fc5c85d07 -r a7351ad54960 Framework/Oracle/GetOrthancImageCommand.cpp --- a/Framework/Oracle/GetOrthancImageCommand.cpp Fri Aug 16 16:24:11 2019 +0200 +++ b/Framework/Oracle/GetOrthancImageCommand.cpp Wed Aug 21 16:16:30 2019 +0200 @@ -45,7 +45,7 @@ GetOrthancImageCommand::GetOrthancImageCommand() : uri_("/"), - timeout_(60), + timeout_(600), hasExpectedFormat_(false) { } diff -r 118fc5c85d07 -r a7351ad54960 Framework/Oracle/GetOrthancWebViewerJpegCommand.cpp --- a/Framework/Oracle/GetOrthancWebViewerJpegCommand.cpp Fri Aug 16 16:24:11 2019 +0200 +++ b/Framework/Oracle/GetOrthancWebViewerJpegCommand.cpp Wed Aug 21 16:16:30 2019 +0200 @@ -49,7 +49,7 @@ GetOrthancWebViewerJpegCommand::GetOrthancWebViewerJpegCommand() : frame_(0), quality_(95), - timeout_(60), + timeout_(600), expectedFormat_(Orthanc::PixelFormat_Grayscale8) { } diff -r 118fc5c85d07 -r a7351ad54960 Framework/Oracle/OracleCommandWithPayload.cpp --- a/Framework/Oracle/OracleCommandWithPayload.cpp Fri Aug 16 16:24:11 2019 +0200 +++ b/Framework/Oracle/OracleCommandWithPayload.cpp Wed Aug 21 16:16:30 2019 +0200 @@ -46,6 +46,7 @@ } else { + LOG(ERROR) << "OracleCommandWithPayload::GetPayload(): (!HasPayload())"; throw Orthanc::OrthancException(Orthanc::ErrorCode_BadSequenceOfCalls); } } @@ -59,6 +60,7 @@ } else { + LOG(ERROR) << "OracleCommandWithPayload::ReleasePayload(): (!HasPayload())"; throw Orthanc::OrthancException(Orthanc::ErrorCode_BadSequenceOfCalls); } } diff -r 118fc5c85d07 -r a7351ad54960 Framework/Oracle/OrthancRestApiCommand.cpp --- a/Framework/Oracle/OrthancRestApiCommand.cpp Fri Aug 16 16:24:11 2019 +0200 +++ b/Framework/Oracle/OrthancRestApiCommand.cpp Wed Aug 21 16:16:30 2019 +0200 @@ -72,6 +72,7 @@ } else { + LOG(ERROR) << "OrthancRestApiCommand::GetBody(): method_ not _Post or _Put"; throw Orthanc::OrthancException(Orthanc::ErrorCode_BadSequenceOfCalls); } } diff -r 118fc5c85d07 -r a7351ad54960 Framework/Oracle/ThreadedOracle.cpp --- a/Framework/Oracle/ThreadedOracle.cpp Fri Aug 16 16:24:11 2019 +0200 +++ b/Framework/Oracle/ThreadedOracle.cpp Wed Aug 21 16:16:30 2019 +0200 @@ -456,6 +456,7 @@ if (state_ != State_Setup) { + LOG(ERROR) << "ThreadedOracle::SetOrthancParameters(): (state_ != State_Setup)"; throw Orthanc::OrthancException(Orthanc::ErrorCode_BadSequenceOfCalls); } else @@ -475,6 +476,7 @@ } else if (state_ != State_Setup) { + LOG(ERROR) << "ThreadedOracle::SetThreadsCount(): (state_ != State_Setup)"; throw Orthanc::OrthancException(Orthanc::ErrorCode_BadSequenceOfCalls); } else @@ -494,6 +496,7 @@ } else if (state_ != State_Setup) { + LOG(ERROR) << "ThreadedOracle::SetSleepingTimeResolution(): (state_ != State_Setup)"; throw Orthanc::OrthancException(Orthanc::ErrorCode_BadSequenceOfCalls); } else @@ -509,6 +512,7 @@ if (state_ != State_Setup) { + LOG(ERROR) << "ThreadedOracle::Start(): (state_ != State_Setup)"; throw Orthanc::OrthancException(Orthanc::ErrorCode_BadSequenceOfCalls); } else diff -r 118fc5c85d07 -r a7351ad54960 Framework/Oracle/WebAssemblyOracle.cpp --- a/Framework/Oracle/WebAssemblyOracle.cpp Fri Aug 16 16:24:11 2019 +0200 +++ b/Framework/Oracle/WebAssemblyOracle.cpp Wed Aug 21 16:16:30 2019 +0200 @@ -308,7 +308,8 @@ if (command_.get() == NULL) { // Cannot call Execute() twice - throw Orthanc::OrthancException(Orthanc::ErrorCode_BadSequenceOfCalls); + LOG(ERROR) << "WebAssemblyOracle::Execute(): (command_.get() == NULL)"; + throw Orthanc::OrthancException(Orthanc::ErrorCode_BadSequenceOfCalls); } emscripten_fetch_attr_t attr; diff -r 118fc5c85d07 -r a7351ad54960 Framework/Scene2D/Internals/OpenGLLinesProgram.cpp --- a/Framework/Scene2D/Internals/OpenGLLinesProgram.cpp Fri Aug 16 16:24:11 2019 +0200 +++ b/Framework/Scene2D/Internals/OpenGLLinesProgram.cpp Wed Aug 21 16:16:30 2019 +0200 @@ -207,6 +207,7 @@ { if (isEmpty_) { + LOG(ERROR) << "OpenGLLinesProgram -- AddTriangles: (isEmpty_)"; throw Orthanc::OrthancException(Orthanc::ErrorCode_BadSequenceOfCalls); } @@ -363,6 +364,7 @@ { if (IsEmpty()) { + LOG(ERROR) << "OpenGLLinesProgram::Data::GetVerticesBuffer(): (IsEmpty())"; throw Orthanc::OrthancException(Orthanc::ErrorCode_BadSequenceOfCalls); } else @@ -376,6 +378,7 @@ { if (IsEmpty()) { + LOG(ERROR) << "OpenGLLinesProgram::Data::GetMiterDirectionsBuffer(): (IsEmpty())"; throw Orthanc::OrthancException(Orthanc::ErrorCode_BadSequenceOfCalls); } else @@ -389,6 +392,7 @@ { if (IsEmpty()) { + LOG(ERROR) << "OpenGLLinesProgram::Data::GetColorsBuffer(): (IsEmpty())"; throw Orthanc::OrthancException(Orthanc::ErrorCode_BadSequenceOfCalls); } else diff -r 118fc5c85d07 -r a7351ad54960 Framework/Scene2D/Internals/OpenGLTextProgram.cpp --- a/Framework/Scene2D/Internals/OpenGLTextProgram.cpp Fri Aug 16 16:24:11 2019 +0200 +++ b/Framework/Scene2D/Internals/OpenGLTextProgram.cpp Wed Aug 21 16:16:30 2019 +0200 @@ -157,6 +157,7 @@ { if (IsEmpty()) { + LOG(ERROR) << "OpenGLTextProgram::Data::GetSceneLocationsBuffer(): (IsEmpty())"; throw Orthanc::OrthancException(Orthanc::ErrorCode_BadSequenceOfCalls); } else @@ -169,6 +170,7 @@ { if (IsEmpty()) { + LOG(ERROR) << "OpenGLTextProgram::Data::GetTextureLocationsBuffer(): (IsEmpty())"; throw Orthanc::OrthancException(Orthanc::ErrorCode_BadSequenceOfCalls); } else diff -r 118fc5c85d07 -r a7351ad54960 Framework/Scene2D/Scene2D.cpp --- a/Framework/Scene2D/Scene2D.cpp Fri Aug 16 16:24:11 2019 +0200 +++ b/Framework/Scene2D/Scene2D.cpp Wed Aug 21 16:16:30 2019 +0200 @@ -48,6 +48,7 @@ { if (layer_.get() == NULL) { + LOG(ERROR) << "Scene2D::Item::GetLayer(): (layer_.get() == NULL)"; throw Orthanc::OrthancException(Orthanc::ErrorCode_BadSequenceOfCalls); } else @@ -60,6 +61,7 @@ { if (layer_.get() == NULL) { + LOG(ERROR) << "Scene2D::Item::ReleaseLayer(): (layer_.get() == NULL)"; throw Orthanc::OrthancException(Orthanc::ErrorCode_BadSequenceOfCalls); } else diff -r 118fc5c85d07 -r a7351ad54960 Framework/Scene2D/TextureBaseSceneLayer.cpp --- a/Framework/Scene2D/TextureBaseSceneLayer.cpp Fri Aug 16 16:24:11 2019 +0200 +++ b/Framework/Scene2D/TextureBaseSceneLayer.cpp Wed Aug 21 16:16:30 2019 +0200 @@ -111,6 +111,7 @@ { if (!HasTexture()) { + LOG(ERROR) << "TextureBaseSceneLayer::GetTexture(): (!HasTexture())"; throw Orthanc::OrthancException(Orthanc::ErrorCode_BadSequenceOfCalls); } else diff -r 118fc5c85d07 -r a7351ad54960 Framework/Toolbox/DicomInstanceParameters.cpp --- a/Framework/Toolbox/DicomInstanceParameters.cpp Fri Aug 16 16:24:11 2019 +0200 +++ b/Framework/Toolbox/DicomInstanceParameters.cpp Wed Aug 21 16:16:30 2019 +0200 @@ -276,6 +276,7 @@ } else { + LOG(ERROR) << "DicomInstanceParameters::GetRescaleIntercept(): !data_.hasRescale_"; throw Orthanc::OrthancException(Orthanc::ErrorCode_BadSequenceOfCalls); } } @@ -289,6 +290,7 @@ } else { + LOG(ERROR) << "DicomInstanceParameters::GetRescaleSlope(): !data_.hasRescale_"; throw Orthanc::OrthancException(Orthanc::ErrorCode_BadSequenceOfCalls); } } @@ -302,6 +304,7 @@ } else { + LOG(ERROR) << "DicomInstanceParameters::GetDefaultWindowingCenter(): !data_.hasRescale_"; throw Orthanc::OrthancException(Orthanc::ErrorCode_BadSequenceOfCalls); } } @@ -315,6 +318,7 @@ } else { + LOG(ERROR) << "DicomInstanceParameters::GetDefaultWindowingWidth(): !data_.hasRescale_"; throw Orthanc::OrthancException(Orthanc::ErrorCode_BadSequenceOfCalls); } } diff -r 118fc5c85d07 -r a7351ad54960 Framework/Toolbox/DicomStructureSet.cpp --- a/Framework/Toolbox/DicomStructureSet.cpp Fri Aug 16 16:24:11 2019 +0200 +++ b/Framework/Toolbox/DicomStructureSet.cpp Wed Aug 21 16:16:30 2019 +0200 @@ -580,6 +580,7 @@ if (referencedSlices_.find(sopInstanceUid) != referencedSlices_.end()) { // This geometry is already known + LOG(ERROR) << "DicomStructureSet::AddReferencedSlice(): (referencedSlices_.find(sopInstanceUid) != referencedSlices_.end()). sopInstanceUid = " << sopInstanceUid; throw Orthanc::OrthancException(Orthanc::ErrorCode_BadSequenceOfCalls); } else @@ -659,7 +660,7 @@ { if (!polygon->UpdateReferencedSlice(referencedSlices_)) { - LOG(ERROR) << "Missing information about referenced instance: " + LOG(ERROR) << "DicomStructureSet::CheckReferencedSlices(): missing information about referenced instance: " << polygon->GetSopInstanceUid(); throw Orthanc::OrthancException(Orthanc::ErrorCode_BadSequenceOfCalls); } diff -r 118fc5c85d07 -r a7351ad54960 Framework/Toolbox/SlicesSorter.cpp --- a/Framework/Toolbox/SlicesSorter.cpp Fri Aug 16 16:24:11 2019 +0200 +++ b/Framework/Toolbox/SlicesSorter.cpp Wed Aug 21 16:16:30 2019 +0200 @@ -72,6 +72,7 @@ } else { + LOG(ERROR) << "SlicesSorter::SliceWithDepth::GetPayload(): (!HasPayload())"; throw Orthanc::OrthancException(Orthanc::ErrorCode_BadSequenceOfCalls); } } @@ -152,6 +153,7 @@ { if (!hasNormal_) { + LOG(ERROR) << "SlicesSorter::SortInternal(): (!hasNormal_)"; throw Orthanc::OrthancException(Orthanc::ErrorCode_BadSequenceOfCalls); } @@ -305,6 +307,7 @@ if (spacingZ <= 0) { + LOG(ERROR) << "SlicesSorter::ComputeSpacingBetweenSlices(): (spacingZ <= 0)"; throw Orthanc::OrthancException(Orthanc::ErrorCode_BadSequenceOfCalls, "Please call the Sort() method before"); } diff -r 118fc5c85d07 -r a7351ad54960 Framework/Viewport/IViewport.h --- a/Framework/Viewport/IViewport.h Fri Aug 16 16:24:11 2019 +0200 +++ b/Framework/Viewport/IViewport.h Wed Aug 21 16:16:30 2019 +0200 @@ -50,12 +50,16 @@ virtual ScenePoint2D GetPixelCenterCoordinates(int x, int y) const = 0; -#if ORTHANC_ENABLE_LOCALE == 1 - virtual void SetFont(size_t index, - Orthanc::EmbeddedResources::FileResourceId resource, - unsigned int fontSize, - Orthanc::Encoding codepage) = 0; -#endif + virtual bool IsContextLost() = 0; + + virtual void* DebugGetInternalContext() const = 0; + +#if ORTHANC_ENABLE_LOCALE == 1 + virtual void SetFont(size_t index, + Orthanc::EmbeddedResources::FileResourceId resource, + unsigned int fontSize, + Orthanc::Encoding codepage) = 0; +#endif protected: virtual ICompositor* GetCompositor() = 0; diff -r 118fc5c85d07 -r a7351ad54960 Framework/Viewport/SdlViewport.cpp --- a/Framework/Viewport/SdlViewport.cpp Fri Aug 16 16:24:11 2019 +0200 +++ b/Framework/Viewport/SdlViewport.cpp Wed Aug 21 16:16:30 2019 +0200 @@ -47,11 +47,26 @@ compositor_.reset(new OpenGLCompositor(context_, GetScene())); } + + void* SdlOpenGLViewport::DebugGetInternalContext() const + { + return context_.DebugGetInternalContext(); + } + + bool SdlOpenGLViewport::IsContextLost() { + return context_.IsContextLost(); + } + bool SdlOpenGLViewport::OpenGLContextLost() { throw Orthanc::OrthancException(Orthanc::ErrorCode_NotImplemented); } + bool SdlOpenGLViewport::OpenGLContextRestored() + { + throw Orthanc::OrthancException(Orthanc::ErrorCode_NotImplemented); + } + void SdlOpenGLViewport::DisableCompositor() { compositor_.reset(NULL); diff -r 118fc5c85d07 -r a7351ad54960 Framework/Viewport/SdlViewport.h --- a/Framework/Viewport/SdlViewport.h Fri Aug 16 16:24:11 2019 +0200 +++ b/Framework/Viewport/SdlViewport.h Wed Aug 21 16:16:30 2019 +0200 @@ -87,7 +87,11 @@ return context_.GetWindow(); } + virtual void* DebugGetInternalContext() const ORTHANC_OVERRIDE; + + virtual bool IsContextLost() ORTHANC_OVERRIDE; bool OpenGLContextLost(); + bool OpenGLContextRestored(); virtual void UpdateSize(unsigned int width, unsigned int height) ORTHANC_OVERRIDE { diff -r 118fc5c85d07 -r a7351ad54960 Framework/Viewport/ViewportBase.h --- a/Framework/Viewport/ViewportBase.h Fri Aug 16 16:24:11 2019 +0200 +++ b/Framework/Viewport/ViewportBase.h Wed Aug 21 16:16:30 2019 +0200 @@ -62,15 +62,15 @@ return 0; } -#if ORTHANC_ENABLE_LOCALE == 1 - virtual void SetFont(size_t index, - Orthanc::EmbeddedResources::FileResourceId resource, - unsigned int fontSize, - Orthanc::Encoding codepage) ORTHANC_OVERRIDE - { - return GetCompositor()->SetFont(index, resource, fontSize, codepage); - } -#endif +#if ORTHANC_ENABLE_LOCALE == 1 + virtual void SetFont(size_t index, + Orthanc::EmbeddedResources::FileResourceId resource, + unsigned int fontSize, + Orthanc::Encoding codepage) ORTHANC_OVERRIDE + { + return GetCompositor()->SetFont(index, resource, fontSize, codepage); + } +#endif private: std::string identifier_; diff -r 118fc5c85d07 -r a7351ad54960 Framework/Viewport/WebAssemblyViewport.cpp --- a/Framework/Viewport/WebAssemblyViewport.cpp Fri Aug 16 16:24:11 2019 +0200 +++ b/Framework/Viewport/WebAssemblyViewport.cpp Wed Aug 21 16:16:30 2019 +0200 @@ -86,9 +86,26 @@ { try { - // the compositor COULD be dead! - if (GetCompositor()) + if (!GetCompositor()) + { + // this block was added because of (perceived?) bugs in the + // browser where the WebGL contexts are NOT automatically restored + // after being lost. + // the WebGL context has been lost. Sce + + //LOG(ERROR) << "About to call WebAssemblyOpenGLContext::TryRecreate()."; + //LOG(ERROR) << "Before calling it, isContextLost == " << context_.IsContextLost(); + + if (!context_.IsContextLost()) { + LOG(ERROR) << "Context restored!"; + //LOG(ERROR) << "After calling it, isContextLost == " << context_.IsContextLost(); + RestoreCompositor(); + UpdateSize(); + } + } + if (GetCompositor()) { GetCompositor()->Refresh(); + } } catch (const OpenGLContextLostException& e) { @@ -103,6 +120,11 @@ } } + bool WebAssemblyOpenGLViewport::IsContextLost() + { + return context_.IsContextLost(); + } + void WebAssemblyOpenGLViewport::RestoreCompositor() { // the context must have been restored! @@ -127,13 +149,27 @@ bool WebAssemblyOpenGLViewport::OpenGLContextRestored() { LOG(ERROR) << "WebAssemblyOpenGLViewport::OpenGLContextRestored() for canvas: " << GetCanvasIdentifier(); - RestoreCompositor(); - UpdateSize(); + + // maybe the context has already been restored by other means (the + // Refresh() function) + if (!GetCompositor()) + { + RestoreCompositor(); + UpdateSize(); + } return false; } + void* WebAssemblyOpenGLViewport::DebugGetInternalContext() const + { + return context_.DebugGetInternalContext(); + } + void WebAssemblyOpenGLViewport::RegisterContextCallbacks() { +#if 0 + // DISABLED ON 2019-08-20 and replaced by external JS calls because I could + // not get emscripten API to work // TODO: what's the impact of userCapture=true ? const char* canvasId = GetCanvasIdentifier().c_str(); void* that = reinterpret_cast(this); @@ -148,6 +184,7 @@ // LOG(ERROR) << msg; // ORTHANC_ASSERT(false, msg.c_str()); //} + status = emscripten_set_webglcontextrestored_callback(canvasId, that, true, WebAssemblyOpenGLViewport_OpenGLContextRestored_callback); if (status != EMSCRIPTEN_RESULT_SUCCESS) { @@ -158,6 +195,7 @@ ORTHANC_ASSERT(false, msg.c_str()); } LOG(TRACE) << "WebAssemblyOpenGLViewport::RegisterContextCallbacks() SUCCESS!!!"; +#endif } WebAssemblyCairoViewport::WebAssemblyCairoViewport(const std::string& canvas) : @@ -209,5 +247,4 @@ LOG(INFO) << "refreshing cairo viewport, TODO: blit to the canvans.getContext('2d')"; GetCompositor()->Refresh(); } - } diff -r 118fc5c85d07 -r a7351ad54960 Framework/Viewport/WebAssemblyViewport.h --- a/Framework/Viewport/WebAssemblyViewport.h Fri Aug 16 16:24:11 2019 +0200 +++ b/Framework/Viewport/WebAssemblyViewport.h Wed Aug 21 16:16:30 2019 +0200 @@ -65,9 +65,18 @@ virtual void Refresh() ORTHANC_OVERRIDE; + virtual bool IsContextLost() ORTHANC_OVERRIDE; + + // this does NOT return whether the context is lost! This is called to + // tell Stone that the context has been lost bool OpenGLContextLost(); + + // This should be called to indicate that the context has been lost bool OpenGLContextRestored(); + + virtual void* DebugGetInternalContext() const ORTHANC_OVERRIDE; + private: virtual void DisableCompositor() ORTHANC_OVERRIDE; virtual void RestoreCompositor() ORTHANC_OVERRIDE; diff -r 118fc5c85d07 -r a7351ad54960 Framework/Volumes/DicomVolumeImage.cpp --- a/Framework/Volumes/DicomVolumeImage.cpp Fri Aug 16 16:24:11 2019 +0200 +++ b/Framework/Volumes/DicomVolumeImage.cpp Wed Aug 21 16:16:30 2019 +0200 @@ -32,6 +32,7 @@ { if (!HasGeometry()) { + LOG(ERROR) << "DicomVolumeImage::CheckHasGeometry(): (!HasGeometry())"; throw Orthanc::OrthancException(Orthanc::ErrorCode_BadSequenceOfCalls); } } @@ -91,6 +92,7 @@ } else { + LOG(ERROR) << "DicomVolumeImage::GetDicomParameters(): (!HasDicomParameters())"; throw Orthanc::OrthancException(Orthanc::ErrorCode_BadSequenceOfCalls); } } diff -r 118fc5c85d07 -r a7351ad54960 Framework/Volumes/DicomVolumeImageMPRSlicer.cpp --- a/Framework/Volumes/DicomVolumeImageMPRSlicer.cpp Fri Aug 16 16:24:11 2019 +0200 +++ b/Framework/Volumes/DicomVolumeImageMPRSlicer.cpp Wed Aug 21 16:16:30 2019 +0200 @@ -33,6 +33,7 @@ { if (!valid_) { + LOG(ERROR) << "DicomVolumeImageMPRSlicer::Slice::CheckValid(): (!valid_)"; throw Orthanc::OrthancException(Orthanc::ErrorCode_BadSequenceOfCalls); } } diff -r 118fc5c85d07 -r a7351ad54960 Framework/Volumes/IVolumeSlicer.cpp --- a/Framework/Volumes/IVolumeSlicer.cpp Fri Aug 16 16:24:11 2019 +0200 +++ b/Framework/Volumes/IVolumeSlicer.cpp Wed Aug 21 16:16:30 2019 +0200 @@ -27,12 +27,14 @@ { uint64_t IVolumeSlicer::InvalidSlice::GetRevision() { + LOG(ERROR) << "IVolumeSlicer::InvalidSlice::GetRevision()"; throw Orthanc::OrthancException(Orthanc::ErrorCode_BadSequenceOfCalls); } ISceneLayer* IVolumeSlicer::InvalidSlice::CreateSceneLayer(const ILayerStyleConfigurator* configurator, const CoordinateSystem3D& cuttingPlane) { + LOG(ERROR) << "IVolumeSlicer::InvalidSlice::CreateSceneLayer()"; throw Orthanc::OrthancException(Orthanc::ErrorCode_BadSequenceOfCalls); } } diff -r 118fc5c85d07 -r a7351ad54960 Framework/Volumes/VolumeReslicer.cpp --- a/Framework/Volumes/VolumeReslicer.cpp Fri Aug 16 16:24:11 2019 +0200 +++ b/Framework/Volumes/VolumeReslicer.cpp Wed Aug 21 16:16:30 2019 +0200 @@ -710,6 +710,8 @@ } else { + LOG(ERROR) << "VolumeReslicer::GetOutputExtent(): (!success_)"; + throw Orthanc::OrthancException(Orthanc::ErrorCode_BadSequenceOfCalls); } } @@ -724,6 +726,7 @@ } else { + LOG(ERROR) << "VolumeReslicer::GetOutputSlice(): (!success_)"; throw Orthanc::OrthancException(Orthanc::ErrorCode_BadSequenceOfCalls); } } @@ -739,6 +742,7 @@ } else { + LOG(ERROR) << "VolumeReslicer::ReleaseOutputSlice(): (!success_)"; throw Orthanc::OrthancException(Orthanc::ErrorCode_BadSequenceOfCalls); } } @@ -828,6 +832,7 @@ } else { + LOG(ERROR) << "VolumeReslicer::GetPixelSpacing(): (!success_)"; throw Orthanc::OrthancException(Orthanc::ErrorCode_BadSequenceOfCalls); } } diff -r 118fc5c85d07 -r a7351ad54960 Framework/Volumes/VolumeSceneLayerSource.cpp --- a/Framework/Volumes/VolumeSceneLayerSource.cpp Fri Aug 16 16:24:11 2019 +0200 +++ b/Framework/Volumes/VolumeSceneLayerSource.cpp Wed Aug 21 16:16:30 2019 +0200 @@ -85,6 +85,7 @@ { if (configurator_.get() == NULL) { + LOG(ERROR) << "VolumeSceneLayerSource::GetConfigurator(): (configurator_.get() == NULL)"; throw Orthanc::OrthancException(Orthanc::ErrorCode_BadSequenceOfCalls); } diff -r 118fc5c85d07 -r a7351ad54960 Platforms/Generic/Oracle.cpp --- a/Platforms/Generic/Oracle.cpp Fri Aug 16 16:24:11 2019 +0200 +++ b/Platforms/Generic/Oracle.cpp Wed Aug 21 16:16:30 2019 +0200 @@ -140,6 +140,7 @@ if (state_ != State_Init) { + LOG(ERROR) << "Oracle::PImpl::Start: (state_ != State_Init)"; throw Orthanc::OrthancException(Orthanc::ErrorCode_BadSequenceOfCalls); } @@ -158,6 +159,7 @@ if (state_ != State_Started) { + LOG(ERROR) << "Oracle::PImpl::Stop(): (state_ != State_Started)"; throw Orthanc::OrthancException(Orthanc::ErrorCode_BadSequenceOfCalls); } diff -r 118fc5c85d07 -r a7351ad54960 README.md --- a/README.md Fri Aug 16 16:24:11 2019 +0200 +++ b/README.md Wed Aug 21 16:16:30 2019 +0200 @@ -236,6 +236,15 @@ url="https://doi.org/10.1007/s10278-018-0082-y" } +Build the Application Samples +----------------------------- + +**Visual Studio 2008 (v90) ** + +``` +cmake -G "Visual Studio 9 2008" -DUSE_LEGACY_JSONCPP=ON -DENABLE_OPENGL=ON -DSTATIC_BUILD=ON -DOPENSSL_NO_CAPIENG=ON -DORTHANC_FRAMEWORK_SOURCE=path -DORTHANC_FRAMEWORK_ROOT="$($pwd)\..\orthanc" -DALLOW_DOWNLOADS=ON -DENABLE_SDL=ON ../orthanc-stone/Applications/Samples +``` + Various notes to be sorted --------------------------- How to build the newest (2019-04-29) SDL samples under Windows, *inside* a