From f75817a5df7139a59c08d67372905d422aac6be8 Mon Sep 17 00:00:00 2001 From: Adam Hunter Date: Wed, 9 Dec 2015 16:49:34 -0800 Subject: [node] Move to using PBOs for the readStillImage call in HeadlessView. --- platform/default/headless_view.cpp | 39 ++++++++++++++++++++++++++++---------- 1 file changed, 29 insertions(+), 10 deletions(-) diff --git a/platform/default/headless_view.cpp b/platform/default/headless_view.cpp index 71fdf5885b..6f0d6c2198 100644 --- a/platform/default/headless_view.cpp +++ b/platform/default/headless_view.cpp @@ -49,23 +49,42 @@ PremultipliedImage HeadlessView::readStillImage() { const unsigned int h = dimensions[1] * pixelRatio; PremultipliedImage image { w, h }; + 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)); + { util::stopwatch stopwatch2("glReadPixels", EventSeverity::Info, Event::General); - MBGL_CHECK_ERROR(glReadPixels(0, 0, w, h, GL_RGBA, GL_UNSIGNED_BYTE, image.data.get())); + MBGL_CHECK_ERROR(glReadPixels(0, 0, w, h, GL_RGBA, GL_UNSIGNED_BYTE, 0)); } - const auto stride = image.stride(); - auto tmp = std::make_unique(stride); - uint8_t* rgba = image.data.get(); - { - util::stopwatch stopwatch3("memcpy", EventSeverity::Info, Event::General); - 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); + // 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(stride); + uint8_t* rgba = image.data.get(); + + { + util::stopwatch stopwatch3("memcpy", EventSeverity::Info, Event::General); + 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; } -- cgit v1.2.1