Beatmup
renderer.cpp
Go to the documentation of this file.
1 /*
2  Beatmup image and signal processing library
3  Copyright (C) 2019, lnstadrum
4 
5  This program is free software: you can redistribute it and/or modify
6  it under the terms of the GNU General Public License as published by
7  the Free Software Foundation, either version 3 of the License, or
8  (at your option) any later version.
9 
10  This program is distributed in the hope that it will be useful,
11  but WITHOUT ANY WARRANTY; without even the implied warranty of
12  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13  GNU General Public License for more details.
14 
15  You should have received a copy of the GNU General Public License
16  along with this program. If not, see <http://www.gnu.org/licenses/>.
17 */
18 
19 #include "renderer.h"
20 #include "../geometry.h"
21 #include "../bitmap/bitmap_access.h"
22 #include "../bitmap/interpolation.h"
23 #include "../bitmap/internal_bitmap.h"
24 #include "../bitmap/tools.h"
25 #include "../exception.h"
26 #include "../gpu/pipeline.h"
27 
28 #include "../debug.h"
29 
30 using namespace Beatmup;
31 
32 
33 /**
34  \internal
35  Recursive scene rendering instruction
36 */
37 void SceneRenderer::renderLayer(RenderingContext& context, TaskThread& thread, Scene::Layer& layer, const AffineMapping& base, unsigned int recursionLevel) {
38  if (recursionLevel >= MAX_RECURSION_LEVEL)
39  return;
40 
41  switch (layer.getType()) {
42 
45  for (int i = 0; i < scene.getLayerCount() && !thread.isTaskAborted(); ++i) {
46  Scene::Layer& l = scene.getLayer(i);
47  if (l.isVisible())
48  renderLayer(context, thread, l, base * layer.getMapping(), recursionLevel + 1);
49  }
50  }
51  break;
52 
53  default:
54  context.setMapping(base * layer.getMapping());
55  layer.render(context);
56  break;
57  }
58 }
59 
60 
62  return scene;
63 }
64 
65 
67  return output;
68 }
69 
70 
72  this->scene = scene;
73 }
74 
75 
77  this->output = output;
78 }
79 
80 
82  this->output = nullptr;
83 }
84 
85 
87  outputMapping = newMapping;
88 }
89 
90 
92  return outputMapping;
93 }
94 
95 
97  referenceWidth = newWidth;
98 }
99 
100 
102  return referenceWidth;
103 }
104 
105 
107  background = bitmap;
108 }
109 
110 
112  this->outputPixelsFetching = fetch;
113 }
114 
115 
117  return outputPixelsFetching;
118 }
119 
120 
121 Scene::Layer* SceneRenderer::pickLayer(float x, float y, bool inPixels) const {
122  if (scene == nullptr)
123  return nullptr;
124  if (inPixels) {
126  return scene->getLayer(p.x, p.y);
127  }
128  else
129  return scene->getLayer(x, y);
130 }
131 
132 
134  this->eventListener = eventListener;
135 }
136 
137 
139  if (eventListener)
141 
142  // reset camera frame
143  cameraFrame = nullptr;
144 }
145 
146 
148  // check if there is the content to render
149  if (!scene)
150  return true;
151 
152  // init rendering context
154  RenderingContext context(gpu, eventListener,
155  resolution,
157  output == nullptr);
158 
159  // set output
160  if (output) {
161  context.writeLock(&gpu, output, ProcessingTarget::GPU);
162  gpu.bindOutput(*output);
163  }
164  else {
165  gpu.unbindOutput();
166  }
167 
168  // background
169  if (background) {
170  context.lockBitmap(background);
172  }
173 
174  // enable blending
176 
177  // compute initial mapping
179  switch (outputMapping) {
180  case FIT_WIDTH_TO_TOP:
182  break;
183  case FIT_WIDTH:
185  outputCoords.setCenterPosition(Point(0.5f, 0.5f));
186  break;
187  case FIT_HEIGHT:
189  outputCoords.setCenterPosition(Point(0.5f, 0.5f));
190  break;
191  case STRETCH:
192  // identity is okay
193  break;
194  }
195 
196  // go
197  for (int i = 0; i < scene->getLayerCount() && !thread.isTaskAborted(); ++i) {
199  if (layer.isVisible())
200  renderLayer(context, thread, layer, outputCoords);
201  }
202 
203  // finalize output
204  if (!thread.isTaskAborted()) {
205  if (!output)
206  gpu.swapBuffers();
207  else if (outputPixelsFetching) {
208  context.writeLock(&gpu, output, ProcessingTarget::CPU);
209  gpu.pullPixels(*output);
210  context.unlock(output);
211  }
212  }
213 
214  // unlock all
215  context.unlockAll();
216  return true;
217 }
218 
219 
221  if (!scene)
222  return true;
223  Scene::LockGuard lock(scene);
224 
225  // go
226  return doRender(gpu, thread);
227 }
228 
229 
231  throw RuntimeError("GPU is required for rendering");
232  return true;
233 }
234 
235 
237  scene(nullptr), background(nullptr), output(nullptr),
238  outputMapping(FIT_WIDTH_TO_TOP),
239  referenceWidth(0),
240  outputPixelsFetching(false),
241  eventListener(nullptr)
242 {}
243 
244 
A very basic class for any image.
const ImageResolution getSize() const
Returns the bitmap resolution within ImageResolution object.
2x3 affine mapping containing a 2x2 matrix and a 2D point
Definition: geometry.h:639
void setCenterPosition(const Point &newPos)
Adjusts the mapping origin so that the center of the axes box matches a given point.
Definition: geometry.cpp:67
AffineMapping getInverse() const
Returns inverse mapping.
Definition: geometry.cpp:52
void unlock(AbstractBitmap *bitmap)
Drops a lock to the bitmap.
void writeLock(GraphicPipeline *gpu, AbstractBitmap *bitmap, ProcessingTarget target)
Locks content of a bitmap for writing using a specific processing target device.
void unlockAll()
Unlocks all the locked bitmaps unconditionally.
void scale(numeric factor)
Definition: geometry.h:399
void paveBackground(GraphicPipeline *gpu, TextureHandler &content, GL::TextureHandler *output)
Fills background with a repeated texture taking 1 pixel of this texture per 1 pixel of the output.
Internal low-level GPU control API.
Definition: pipeline.h:33
void switchMode(Mode mode)
Switches GPU mode.
Definition: pipeline.cpp:941
const ImageResolution & getDisplayResolution() const
Definition: pipeline.cpp:916
void pullPixels(AbstractBitmap &bitmap)
Transfers bitmap pixels from GPU to CPU.
Definition: pipeline.cpp:921
void bindOutput(AbstractBitmap &bitmap)
Binds a bitmap to the pipeline output.
Definition: pipeline.cpp:891
@ RENDERING
Textures are images to be blended together to produce another image.
void unbindOutput()
Unbinds a bitmap from output and switches to screen.
Definition: pipeline.cpp:911
GL::RenderingPrograms & getRenderingPrograms()
Definition: pipeline.h:125
unsigned int getWidth() const
unsigned int getHeight() const
Stores the rendering context: current program, current mapping in the scene space,...
void setMapping(const AffineMapping &mapping)
void lockBitmap(AbstractBitmap *bitmap)
bool getOutputPixelsFetching() const
Reports whether the output bitmap pixels are automatically offloaded from GPU to CPU memory every tim...
Definition: renderer.cpp:116
bool process(TaskThread &thread)
Executes the task on CPU within a given thread.
Definition: renderer.cpp:230
RenderingContext::EventListener * eventListener
Definition: renderer.h:51
void setScene(Scene *scene)
Definition: renderer.cpp:71
AffineMapping outputCoords
the actual output mapping used during the last rendering
Definition: renderer.h:46
OutputMapping
Scene coordinates to output (screen or bitmap) pixel coordinates mapping.
Definition: renderer.h:34
@ STRETCH
output viewport covers entirely the scene axis span, aspect ratio is not preserved in general
Definition: renderer.h:35
@ FIT_HEIGHT
height is covered entirely, width is resized to keep aspect ratio, point (0.5, 0.5) is mapped to the ...
Definition: renderer.h:38
@ FIT_WIDTH
width is covered entirely, height is resized to keep aspect ratio, point (0.5, 0.5) is mapped to the ...
Definition: renderer.h:37
@ FIT_WIDTH_TO_TOP
width is covered entirely, height is resized to keep aspect ratio, the top borders are aligned
Definition: renderer.h:36
int referenceWidth
value overriding output width for elements that have their size in pixels, in order to render a resol...
Definition: renderer.h:48
void resetOutput()
Removes a bitmap from the renderer output, if any, and switches to on-screen rendering.
Definition: renderer.cpp:81
void setOutputPixelsFetching(bool fetch)
Specifies whether the output image data is pulled from GPU to CPU memory every time the rendering is ...
Definition: renderer.cpp:111
void setOutputMapping(const OutputMapping mapping)
Specifies the output mapping specifying how the scene coordinates [0,1]² are mapped to the output (sc...
Definition: renderer.cpp:86
ImageResolution resolution
last rendered resolution
Definition: renderer.h:47
AbstractBitmap * output
output bitmap
Definition: renderer.h:44
bool processOnGPU(GraphicPipeline &gpu, TaskThread &thread)
Executes the task on GPU.
Definition: renderer.cpp:220
Scene * scene
content to render
Definition: renderer.h:42
void setRenderingEventListener(RenderingContext::EventListener *eventListener)
Definition: renderer.cpp:133
bool outputPixelsFetching
if true, the output bitmap data is fetched from GPU to CPU RAM every time the rendering is done
Definition: renderer.h:49
static const unsigned int MAX_RECURSION_LEVEL
Definition: renderer.h:54
void setOutput(AbstractBitmap *bitmap)
Attaches a bitmap to the renderer output.
Definition: renderer.cpp:76
const Scene * getScene() const
Definition: renderer.cpp:61
void setBackgroundImage(AbstractBitmap *)
Sets an image to pave the background.
Definition: renderer.cpp:106
Scene::Layer * pickLayer(float x, float y, bool inPixels) const
Retrieves a scene layer visible at a given point, if any.
Definition: renderer.cpp:121
OutputMapping outputMapping
specifies how the scene coordinates [0,1] are mapped to the output (screen or bitmap)
Definition: renderer.h:45
void beforeProcessing(ThreadIndex threadCount, ProcessingTarget target, GraphicPipeline *gpu)
Instruction called before the task is executed.
Definition: renderer.cpp:138
void renderLayer(RenderingContext &context, TaskThread &thread, Scene::Layer &layer, const AffineMapping &base, unsigned int recursionLevel=0)
Definition: renderer.cpp:37
GL::TextureHandler * cameraFrame
last got camera frame; set to NULL before rendering, then asked from outside through eventListener
Definition: renderer.h:50
OutputMapping getOutputMapping() const
Retrieves the output mapping specifying how the scene coordinates [0,1]² are mapped to the output (sc...
Definition: renderer.cpp:91
int getOutputReferenceWidth() const
Definition: renderer.cpp:101
bool doRender(GraphicPipeline &gpu, TaskThread &thread)
Definition: renderer.cpp:147
AbstractBitmap * background
used to pave the screen before rendering
Definition: renderer.h:43
AbstractBitmap * getOutput() const
Definition: renderer.cpp:66
void setOutputReferenceWidth(int newWidth)
Sets a value overriding output width for elements that have their size in pixels, in order to render ...
Definition: renderer.cpp:96
Abstract scene layer having name, type, geometry and some content to display.
Definition: scene.h:64
@ SceneLayer
layer containing a scene
bool isVisible() const
Returns layer visibility flag.
Definition: scene.h:114
virtual void render(RenderingContext &context)
Definition: scene.h:78
Type getType() const
Definition: scene.h:92
AffineMapping & getMapping()
Definition: scene.h:97
LayerType & castTo() const
Definition: scene.h:132
Layer containing an entire scene.
Definition: scene.h:141
An ordered set of layers representing a renderable content.
Definition: scene.h:37
Layer * getLayer(const char *name) const
Retrieves a layer by its name or null if not found.
Definition: scene.cpp:163
int getLayerCount() const
Returns total number of layers in the scene.
Definition: scene.cpp:199
Thread executing tasks.
Definition: parallelism.h:154
virtual bool isTaskAborted() const =0
Returns true if the task is asked to stop from outside.
unsigned char ThreadIndex
number of threads / thread index
Definition: parallelism.h:68
CustomPoint< float > Point
Definition: geometry.h:626
ProcessingTarget
Definition: basic_types.h:55
JNIEnv jlong jint background
jobject jlong jint jint y
jobject jlong jint x
Beatmup::InternalBitmap * bitmap
Beatmup::Scene::Layer * layer
jlong jboolean inPixels
jlong jboolean fetch
Beatmup::IntPoint p((int) x,(int) y)
return $pool getJavaReference & scene(index)