Mercurial > hg > orthanc-stone
comparison Framework/Viewport/SdlViewport.cpp @ 1216:5147277850cf broker
better abstraction for IViewport
author | Sebastien Jodogne <s.jodogne@gmail.com> |
---|---|
date | Thu, 05 Dec 2019 16:36:40 +0100 |
parents | 86a8266b8888 |
children | c04d0aa40f73 |
comparison
equal
deleted
inserted
replaced
1215:9efa66d8d3f8 | 1216:5147277850cf |
---|---|
22 | 22 |
23 #include <Core/OrthancException.h> | 23 #include <Core/OrthancException.h> |
24 | 24 |
25 namespace OrthancStone | 25 namespace OrthancStone |
26 { | 26 { |
27 SdlViewport::SdlViewport() | 27 ICompositor& SdlViewport::SdlLock::GetCompositor() |
28 { | |
29 if (that_.compositor_.get() == NULL) | |
30 { | |
31 // The derived class should have called "AcquireCompositor()" | |
32 throw Orthanc::OrthancException(Orthanc::ErrorCode_InternalError); | |
33 } | |
34 else | |
35 { | |
36 return *that_.compositor_; | |
37 } | |
38 } | |
39 | |
40 | |
41 void SdlViewport::AcquireCompositor(ICompositor* compositor /* takes ownership */) | |
42 { | |
43 if (compositor == NULL) | |
44 { | |
45 throw Orthanc::OrthancException(Orthanc::ErrorCode_NullPointer); | |
46 } | |
47 | |
48 compositor_.reset(compositor); | |
49 } | |
50 | |
51 | |
52 SdlViewport::SdlViewport() : | |
53 controller_(new ViewportController) | |
28 { | 54 { |
29 refreshEvent_ = SDL_RegisterEvents(1); | 55 refreshEvent_ = SDL_RegisterEvents(1); |
30 | 56 |
31 if (refreshEvent_ == static_cast<uint32_t>(-1)) | 57 if (refreshEvent_ == static_cast<uint32_t>(-1)) |
32 { | 58 { |
48 unsigned int width, | 74 unsigned int width, |
49 unsigned int height, | 75 unsigned int height, |
50 bool allowDpiScaling) : | 76 bool allowDpiScaling) : |
51 context_(title, width, height, allowDpiScaling) | 77 context_(title, width, height, allowDpiScaling) |
52 { | 78 { |
53 compositor_.reset(new OpenGLCompositor(context_)); | 79 AcquireCompositor(new OpenGLCompositor(context_)); // (*) |
54 } | 80 } |
55 | 81 |
56 void SdlOpenGLViewport::Invalidate() | 82 |
57 { | 83 SdlOpenGLViewport::~SdlOpenGLViewport() |
58 SendRefreshEvent(); | 84 { |
59 } | 85 // Make sure that the "OpenGLCompositor" is destroyed BEFORE the |
60 | 86 // "OpenGLContext" it references (*) |
61 void SdlOpenGLViewport::Paint(const Scene2D& scene) | 87 ClearCompositor(); |
62 { | 88 } |
63 boost::mutex::scoped_lock lock(mutex_); | 89 |
64 compositor_->Refresh(scene); | 90 |
65 } | 91 void SdlOpenGLViewport::Paint() |
92 { | |
93 SdlLock lock(*this); | |
94 lock.GetCompositor().Refresh(lock.GetController().GetScene()); | |
95 } | |
96 | |
97 | |
98 void SdlOpenGLViewport::UpdateSize(unsigned int width, | |
99 unsigned int height) | |
100 { | |
101 // nothing to do in OpenGL, the OpenGLCompositor::UpdateSize will be called automatically | |
102 SdlLock lock(*this); | |
103 lock.Invalidate(); | |
104 } | |
105 | |
106 | |
107 void SdlOpenGLViewport::ToggleMaximize() | |
108 { | |
109 // No need to call "Invalidate()" here, as "UpdateSize()" will | |
110 // be invoked after event "SDL_WINDOWEVENT_SIZE_CHANGED" | |
111 SdlLock lock(*this); | |
112 context_.ToggleMaximize(); | |
113 } | |
114 | |
66 | 115 |
67 | 116 |
68 SdlCairoViewport::SdlCairoViewport(const char* title, | 117 SdlCairoViewport::SdlCairoViewport(const char* title, |
69 unsigned int width, | 118 unsigned int width, |
70 unsigned int height, | 119 unsigned int height, |
71 bool allowDpiScaling) : | 120 bool allowDpiScaling) : |
72 window_(title, width, height, false /* enable OpenGL */, allowDpiScaling), | 121 window_(title, width, height, false /* enable OpenGL */, allowDpiScaling), |
73 compositor_(width, height), | |
74 sdlSurface_(NULL) | 122 sdlSurface_(NULL) |
75 { | 123 { |
124 AcquireCompositor(new CairoCompositor(width, height)); | |
76 } | 125 } |
77 | 126 |
78 SdlCairoViewport::~SdlCairoViewport() | 127 SdlCairoViewport::~SdlCairoViewport() |
79 { | 128 { |
80 if (sdlSurface_) | 129 if (sdlSurface_) |
81 { | 130 { |
82 SDL_FreeSurface(sdlSurface_); | 131 SDL_FreeSurface(sdlSurface_); |
83 } | 132 } |
84 } | 133 } |
85 | 134 |
86 void SdlCairoViewport::Paint(const Scene2D& scene) | 135 void SdlCairoViewport::Paint() |
87 { | 136 { |
88 boost::mutex::scoped_lock lock(mutex_); | 137 SdlLock lock(*this); |
89 | 138 |
90 compositor_.Refresh(scene); | 139 lock.GetCompositor().Refresh(lock.GetController().GetScene()); |
91 CreateSdlSurfaceFromCompositor(); | 140 CreateSdlSurfaceFromCompositor(dynamic_cast<CairoCompositor&>(lock.GetCompositor())); |
92 | 141 |
93 if (sdlSurface_ != NULL) | 142 if (sdlSurface_ != NULL) |
94 { | 143 { |
95 window_.Render(sdlSurface_); | 144 window_.Render(sdlSurface_); |
96 } | 145 } |
97 } | 146 } |
98 | 147 |
99 void SdlCairoViewport::Invalidate() | |
100 { | |
101 SendRefreshEvent(); | |
102 } | |
103 | 148 |
104 void SdlCairoViewport::UpdateSize(unsigned int width, | 149 void SdlCairoViewport::UpdateSize(unsigned int width, |
105 unsigned int height) | 150 unsigned int height) |
106 { | 151 { |
107 { | 152 SdlLock lock(*this); |
108 boost::mutex::scoped_lock lock(mutex_); | 153 dynamic_cast<CairoCompositor&>(lock.GetCompositor()).UpdateSize(width, height); |
109 compositor_.UpdateSize(width, height); | 154 lock.Invalidate(); |
110 } | 155 } |
111 | 156 |
112 Invalidate(); | 157 |
113 } | 158 void SdlCairoViewport::ToggleMaximize() |
114 | 159 { |
115 void SdlCairoViewport::CreateSdlSurfaceFromCompositor() // Assumes that the mutex is locked | 160 // No need to call "Invalidate()" here, as "UpdateSize()" will |
161 // be invoked after event "SDL_WINDOWEVENT_SIZE_CHANGED" | |
162 SdlLock lock(*this); | |
163 window_.ToggleMaximize(); | |
164 } | |
165 | |
166 | |
167 // Assumes that the mutex is locked | |
168 void SdlCairoViewport::CreateSdlSurfaceFromCompositor(CairoCompositor& compositor) | |
116 { | 169 { |
117 static const uint32_t rmask = 0x00ff0000; | 170 static const uint32_t rmask = 0x00ff0000; |
118 static const uint32_t gmask = 0x0000ff00; | 171 static const uint32_t gmask = 0x0000ff00; |
119 static const uint32_t bmask = 0x000000ff; | 172 static const uint32_t bmask = 0x000000ff; |
120 | 173 |
121 const unsigned int width = compositor_.GetCanvas().GetWidth(); | 174 const unsigned int width = compositor.GetCanvas().GetWidth(); |
122 const unsigned int height = compositor_.GetCanvas().GetHeight(); | 175 const unsigned int height = compositor.GetCanvas().GetHeight(); |
176 | |
177 printf("%dx%d\n", width, height); | |
123 | 178 |
124 if (sdlSurface_ != NULL) | 179 if (sdlSurface_ != NULL) |
125 { | 180 { |
126 if (sdlSurface_->pixels == compositor_.GetCanvas().GetBuffer() && | 181 if (sdlSurface_->pixels == compositor.GetCanvas().GetBuffer() && |
127 sdlSurface_->w == static_cast<int>(width) && | 182 sdlSurface_->w == static_cast<int>(width) && |
128 sdlSurface_->h == static_cast<int>(height) && | 183 sdlSurface_->h == static_cast<int>(height) && |
129 sdlSurface_->pitch == static_cast<int>(compositor_.GetCanvas().GetPitch())) | 184 sdlSurface_->pitch == static_cast<int>(compositor.GetCanvas().GetPitch())) |
130 { | 185 { |
131 // The image from the compositor has not changed, no need to update the surface | 186 // The image from the compositor has not changed, no need to update the surface |
132 return; | 187 return; |
133 } | 188 } |
134 else | 189 else |
135 { | 190 { |
136 SDL_FreeSurface(sdlSurface_); | 191 SDL_FreeSurface(sdlSurface_); |
137 } | 192 } |
138 } | 193 } |
139 | 194 |
140 sdlSurface_ = SDL_CreateRGBSurfaceFrom((void*)(compositor_.GetCanvas().GetBuffer()), width, height, 32, | 195 sdlSurface_ = SDL_CreateRGBSurfaceFrom((void*)(compositor.GetCanvas().GetBuffer()), width, height, 32, |
141 compositor_.GetCanvas().GetPitch(), rmask, gmask, bmask, 0); | 196 compositor.GetCanvas().GetPitch(), rmask, gmask, bmask, 0); |
142 if (!sdlSurface_) | 197 if (!sdlSurface_) |
143 { | 198 { |
144 LOG(ERROR) << "Cannot create a SDL surface from a Cairo surface"; | 199 LOG(ERROR) << "Cannot create a SDL surface from a Cairo surface"; |
145 throw Orthanc::OrthancException(Orthanc::ErrorCode_InternalError); | 200 throw Orthanc::OrthancException(Orthanc::ErrorCode_InternalError); |
146 } | 201 } |