aboutsummaryrefslogtreecommitdiffstats
path: root/platform/default/headless_view.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'platform/default/headless_view.cpp')
-rw-r--r--platform/default/headless_view.cpp36
1 files changed, 27 insertions, 9 deletions
diff --git a/platform/default/headless_view.cpp b/platform/default/headless_view.cpp
index 7fd3c37f3..dda2f6ca3 100644
--- a/platform/default/headless_view.cpp
+++ b/platform/default/headless_view.cpp
@@ -176,17 +176,35 @@ PremultipliedImage HeadlessView::readStillImage() {
const unsigned int h = dimensions[1] * pixelRatio;
PremultipliedImage image { w, h };
- MBGL_CHECK_ERROR(glReadPixels(0, 0, w, h, GL_RGBA, GL_UNSIGNED_BYTE, image.data.get()));
-
- const int stride = image.stride();
- auto tmp = std::make_unique<uint8_t[]>(stride);
- uint8_t* rgba = image.data.get();
- for (int i = 0, j = h - 1; i < j; i++, j--) {
- std::memcpy(tmp.get(), rgba + i * stride, stride);
- std::memcpy(rgba + i * stride, rgba + j * stride, stride);
- std::memcpy(rgba + j * stride, tmp.get(), stride);
+ GLuint bufferId;
+
+ MBGL_CHECK_ERROR(glGenBuffers(1, &bufferId));
+ MBGL_CHECK_ERROR(glBindBuffer(GL_PIXEL_PACK_BUFFER, bufferId));
+ MBGL_CHECK_ERROR(glBufferData(GL_PIXEL_PACK_BUFFER, h * image.stride(), 0, GL_STREAM_READ));
+ MBGL_CHECK_ERROR(glReadPixels(0, 0, w, h, GL_RGBA, GL_UNSIGNED_BYTE, 0));
+
+ // map the PBO to process its data by CPU
+ GLubyte* ptr = (GLubyte*)glMapBuffer(GL_PIXEL_PACK_BUFFER, GL_READ_ONLY);
+
+ if (ptr) {
+ const int stride = image.stride();
+ auto tmp = std::make_unique<uint8_t[]>(stride);
+ uint8_t* rgba = image.data.get();
+
+ for (unsigned int i = 0, j = h - 1; i < h; i++, j--) {
+ std::memcpy(rgba + i * stride, ptr + j * stride, stride);
+ }
+
+ MBGL_CHECK_ERROR(glUnmapBuffer(GL_PIXEL_PACK_BUFFER));
+ } else {
+ throw std::runtime_error(std::string("Could not map buffer on return from read pixels."));
}
+ MBGL_CHECK_ERROR(glDeleteBuffers(1, &bufferId));
+
+ // back to conventional pixel operation
+ MBGL_CHECK_ERROR(glBindBuffer(GL_PIXEL_PACK_BUFFER, 0));
+
return image;
}