Beatmup
storage_buffer.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 "storage_buffer.h"
20 #include "bgl.h"
21 #include "recycle_bin.h"
22 #include "../exception.h"
23 #include <cstring>
24 
25 #ifndef BEATMUP_OPENGLVERSION_GLES20
26 
27 using namespace Beatmup;
28 using namespace GL;
29 
31  sizeBytes(0), recycleBin(recycleBin), handle(0)
32 {}
33 
34 
36  class Deleter : public GL::RecycleBin::Item {
37  private:
38  const handle_t handle;
39  public:
40  Deleter(handle_t handle) : handle(handle) {}
41  ~Deleter() {
42  glDeleteBuffers(1, &handle);
43  }
44  };
45 
46  if (handle)
47  recycleBin.put(new Deleter(handle));
48 }
49 
50 
51 void StorageBuffer::allocate(GraphicPipeline& gpu, const size_t sizeBytes, const void* data) {
52  if (handle && this->sizeBytes != sizeBytes) {
53  glDeleteBuffers(1, &handle);
54  handle = 0;
55  }
56 
57  if (!handle && sizeBytes > 0) {
58  glGenBuffers(1, &handle);
59  glBindBuffer(GL_SHADER_STORAGE_BUFFER, handle);
60  glBufferData(GL_SHADER_STORAGE_BUFFER, sizeBytes, data, GL_DYNAMIC_COPY);
61  }
62 
63  this->sizeBytes = sizeBytes;
64 }
65 
66 void Beatmup::GL::StorageBuffer::allocateStatic(GraphicPipeline& gpu, const size_t sizeBytes, const void* data) {
67  if (handle && this->sizeBytes != sizeBytes) {
68  glDeleteBuffers(1, &handle);
69  handle = 0;
70  }
71 
72  if (!handle && sizeBytes > 0) {
73  glGenBuffers(1, &handle);
74  glBindBuffer(GL_SHADER_STORAGE_BUFFER, handle);
75  glBufferData(GL_SHADER_STORAGE_BUFFER, sizeBytes, data, GL_STATIC_DRAW);
76  }
77 
78  this->sizeBytes = sizeBytes;
79 }
80 
81 
82 void StorageBuffer::bind(GraphicPipeline& gpu, int unit) const {
83  glBindBufferBase(GL_SHADER_STORAGE_BUFFER, unit, handle);
84  GLException::check("binding storage buffer");
85 }
86 
87 
88 void StorageBuffer::fetch(GraphicPipeline& gpu, void* data, size_t limit) {
89  glBindBuffer(GL_SHADER_STORAGE_BUFFER, handle);
90  void* buffer = glMapBufferRange(GL_SHADER_STORAGE_BUFFER, 0, limit, GL_MAP_READ_BIT);
91  const bool okay = buffer != nullptr;
92  if (okay)
93  memcpy(data, buffer, limit);
94  glUnmapBuffer(GL_SHADER_STORAGE_BUFFER);
95  glBindBuffer(GL_SHADER_STORAGE_BUFFER, 0);
96  GLException::check("reading storage buffer");
97  if (!okay)
98  throw RuntimeError("Buffer data not available");
99 }
100 
102  Beatmup::RuntimeError::check(!bitmap.isMask(), "Mask bitmaps are not supported");
103 
104  const size_t limit = offset + stride * (bitmap.getSize().numPixels() - 1) + bitmap.getBitsPerPixel() / 8;
105  Beatmup::RuntimeError::check(getCurrentCapacity() >= limit, "Bitmap does not fit the buffer content");
107 
108  glBindBuffer(GL_SHADER_STORAGE_BUFFER, handle);
109  const pixbyte* buffer = (const pixbyte*)glMapBufferRange(GL_SHADER_STORAGE_BUFFER, offset, limit - offset, GL_MAP_READ_BIT);
110  const bool okay = buffer != nullptr;
111  if (okay) {
112  pixbyte* ptr = bitmap.getData(0, 0);
113  const int
114  nPix = bitmap.getSize().numPixels(),
115  step = bitmap.getBitsPerPixel() / 8;
116  for (int i = 0; i < nPix; ++i, ptr += step, buffer += stride)
117  memcpy(ptr, buffer, step);
118  }
119  glUnmapBuffer(GL_SHADER_STORAGE_BUFFER);
120  glBindBuffer(GL_SHADER_STORAGE_BUFFER, 0);
121 }
122 
123 
124 
125 StorageBufferFetcher::StorageBufferFetcher(StorageBuffer& buffer, void* outputBuffer, size_t outputBufferSize) :
126  buffer(buffer), outputBuffer(outputBuffer), outputBufferSize(outputBufferSize)
127 {}
128 
129 
132  return true;
133 }
134 
135 #endif
Makes a bitmap writable for a specific target device.
A very basic class for any image.
const ImageResolution getSize() const
Returns the bitmap resolution within ImageResolution object.
const unsigned char getBitsPerPixel() const
Returns number of bits per pixel stored in each bitmap.
bool isMask() const
Returns true if the bitmap is a mask, false otherwise.
static void check(const std::string &info)
Definition: bgl.h:62
A wrapper for a GPU resource.
Definition: recycle_bin.h:39
Stores references to GPU resources that will not be used anymore and needed to be recycled in a threa...
Definition: recycle_bin.h:34
void put(Item *item)
Puts an item into the recycle bin.
Definition: recycle_bin.cpp:73
bool processOnGPU(GraphicPipeline &gpu, TaskThread &thread)
Executes the task on GPU.
StorageBufferFetcher(StorageBuffer &buffer, void *outputBuffer, size_t outputBufferSize)
void fetch(GraphicPipeline &gpu, void *data, size_t limit)
GL::RecycleBin & recycleBin
StorageBuffer(GL::RecycleBin &recycleBin)
void bind(GraphicPipeline &gpu, int unit) const
void allocate(GraphicPipeline &gpu, const size_t sizeBytes, const void *data=nullptr)
void fetchToBitmap(GraphicPipeline &gpu, size_t offset, size_t stride, AbstractBitmap &bitmap)
Copies buffer content to a bitmap.
void allocateStatic(GraphicPipeline &gpu, const size_t sizeBytes, const void *data)
Internal low-level GPU control API.
Definition: pipeline.h:33
const pixbyte * getData(int x, int y) const
Returns a pointer to given pixel.
static void check(const bool condition, const std::string &message)
Definition: exception.h:64
Thread executing tasks.
Definition: parallelism.h:154
unsigned int handle_t
A reference to a GPU resource.
Definition: basic_types.h:61
uint8_t pixbyte
Definition: basic_types.h:34
JNIEnv jobject jlong handle
Beatmup::InternalBitmap * bitmap
jlong jint jfloat step