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 }