comparison Applications/Resources/Graveyard/Threading/SdlBuffering.cpp @ 1586:b5417e377636

reorganization
author Sebastien Jodogne <s.jodogne@gmail.com>
date Thu, 22 Oct 2020 16:17:10 +0200
parents OrthancStone/Resources/Graveyard/Threading/SdlBuffering.cpp@244ad1e4e76a
children 4fb8fdf03314
comparison
equal deleted inserted replaced
1585:94edbfa64c97 1586:b5417e377636
1 /**
2 * Stone of Orthanc
3 * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
4 * Department, University Hospital of Liege, Belgium
5 * Copyright (C) 2017-2020 Osimis S.A., Belgium
6 *
7 * This program is free software: you can redistribute it and/or
8 * modify it under the terms of the GNU Affero General Public License
9 * as published by the Free Software Foundation, either version 3 of
10 * the License, or (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Affero General Public License for more details.
16 *
17 * You should have received a copy of the GNU Affero General Public License
18 * along with this program. If not, see <http://www.gnu.org/licenses/>.
19 **/
20
21
22 #include "SdlBuffering.h"
23
24 #if ORTHANC_ENABLE_SDL == 1
25
26 #include "../../Resources/Orthanc/Core/Logging.h"
27 #include "../../Resources/Orthanc/Core/OrthancException.h"
28
29 namespace OrthancStone
30 {
31 SdlBuffering::SdlBuffering() :
32 sdlSurface_(NULL),
33 pendingFrame_(false)
34 {
35 }
36
37
38 SdlBuffering::~SdlBuffering()
39 {
40 if (sdlSurface_)
41 {
42 SDL_FreeSurface(sdlSurface_);
43 }
44 }
45
46
47 void SdlBuffering::SetSize(unsigned int width,
48 unsigned int height,
49 IViewport& viewport)
50 {
51 boost::mutex::scoped_lock lock(mutex_);
52
53 viewport.SetSize(width, height);
54
55 if (offscreenSurface_.get() == NULL ||
56 offscreenSurface_->GetWidth() != width ||
57 offscreenSurface_->GetHeight() != height)
58 {
59 offscreenSurface_.reset(new CairoSurface(width, height));
60 }
61
62 if (onscreenSurface_.get() == NULL ||
63 onscreenSurface_->GetWidth() != width ||
64 onscreenSurface_->GetHeight() != height)
65 {
66 onscreenSurface_.reset(new CairoSurface(width, height));
67
68 // TODO Big endian?
69 static const uint32_t rmask = 0x00ff0000;
70 static const uint32_t gmask = 0x0000ff00;
71 static const uint32_t bmask = 0x000000ff;
72
73 if (sdlSurface_)
74 {
75 SDL_FreeSurface(sdlSurface_);
76 }
77
78 sdlSurface_ = SDL_CreateRGBSurfaceFrom(onscreenSurface_->GetBuffer(), width, height, 32,
79 onscreenSurface_->GetPitch(), rmask, gmask, bmask, 0);
80 if (!sdlSurface_)
81 {
82 LOG(ERROR) << "Cannot create a SDL surface from a Cairo surface";
83 throw Orthanc::OrthancException(Orthanc::ErrorCode_InternalError);
84 }
85 }
86
87 pendingFrame_ = false;
88 }
89
90
91 bool SdlBuffering::RenderOffscreen(IViewport& viewport)
92 {
93 boost::mutex::scoped_lock lock(mutex_);
94
95 if (offscreenSurface_.get() == NULL)
96 {
97 return false;
98 }
99
100 Orthanc::ImageAccessor target = offscreenSurface_->GetAccessor();
101
102 if (viewport.Render(target) &&
103 !pendingFrame_)
104 {
105 pendingFrame_ = true;
106 return true;
107 }
108 else
109 {
110 return false;
111 }
112 }
113
114
115 void SdlBuffering::SwapToScreen(SdlWindow& window)
116 {
117 if (!pendingFrame_ ||
118 offscreenSurface_.get() == NULL ||
119 onscreenSurface_.get() == NULL)
120 {
121 return;
122 }
123
124 {
125 boost::mutex::scoped_lock lock(mutex_);
126 onscreenSurface_->Copy(*offscreenSurface_);
127 }
128
129 window.Render(sdlSurface_);
130 pendingFrame_ = false;
131 }
132 }
133
134 #endif