LCOV - code coverage report
Current view: top level - eq/compressor - compressorReadDrawPixels.cpp (source / functions) Hit Total Coverage
Test: Equalizer Lines: 103 294 35.0 %
Date: 2017-12-16 05:07:20 Functions: 72 77 93.5 %

          Line data    Source code
       1             : 
       2             : /* Copyright (c) 2010-2017, Cedric Stalder <cedric.stalder@eyescale.ch>
       3             :  *                          Stefan Eilemann <eile@eyescale.ch>
       4             :  *                          Daniel Nachbaur <danielnachbaur@gmail.com>
       5             :  *
       6             :  * This library is free software; you can redistribute it and/or modify it under
       7             :  * the terms of the GNU Lesser General Public License version 2.1 as published
       8             :  * by the Free Software Foundation.
       9             :  *
      10             :  * This library is distributed in the hope that it will be useful, but WITHOUT
      11             :  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
      12             :  * FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License for more
      13             :  * details.
      14             :  *
      15             :  * You should have received a copy of the GNU Lesser General Public License
      16             :  * along with this library; if not, write to the Free Software Foundation, Inc.,
      17             :  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
      18             :  */
      19             : 
      20             : #include "compressorReadDrawPixels.h"
      21             : 
      22             : #include <eq/fabric/pixelViewport.h>
      23             : #include <eq/util/pixelBufferObject.h>
      24             : #include <eq/util/texture.h>
      25             : #include <lunchbox/buffer.h>
      26             : #include <unordered_map>
      27             : 
      28             : #define glewGetContext() glewContext
      29             : 
      30             : namespace eq
      31             : {
      32             : namespace plugin
      33             : {
      34             : namespace
      35             : {
      36             : int _warned = 0;
      37           6 : static std::unordered_map<unsigned, unsigned> _depths;
      38             : 
      39             : #define REGISTER_TRANSFER(in, out, size, quality_, ratio_, speed_, alpha)     \
      40             :     static void _getInfo##in##out(EqCompressorInfo* const info)               \
      41             :     {                                                                         \
      42             :         info->version = EQ_COMPRESSOR_VERSION;                                \
      43             :         info->capabilities =                                                  \
      44             :             EQ_COMPRESSOR_TRANSFER | EQ_COMPRESSOR_DATA_2D |                  \
      45             :             EQ_COMPRESSOR_USE_TEXTURE_RECT | EQ_COMPRESSOR_USE_TEXTURE_2D |   \
      46             :             EQ_COMPRESSOR_USE_ASYNC_DOWNLOAD | EQ_COMPRESSOR_USE_FRAMEBUFFER; \
      47             :         if (alpha)                                                            \
      48             :             info->capabilities |= EQ_COMPRESSOR_IGNORE_ALPHA;                 \
      49             :         info->quality = quality_##f;                                          \
      50             :         info->ratio = ratio_##f;                                              \
      51             :         info->speed = speed_##f;                                              \
      52             :         info->name = EQ_COMPRESSOR_TRANSFER_##in##_TO_##out;                  \
      53             :         info->tokenType = EQ_COMPRESSOR_DATATYPE_##in;                        \
      54             :         info->outputTokenType = EQ_COMPRESSOR_DATATYPE_##out;                 \
      55             :         info->outputTokenSize = size;                                         \
      56             :     }                                                                         \
      57             :                                                                               \
      58             :     static bool _register##in##out()                                          \
      59             :     {                                                                         \
      60             :         const unsigned name = EQ_COMPRESSOR_TRANSFER_##in##_TO_##out;         \
      61             :         Compressor::registerEngine(Compressor::Functions(                     \
      62             :             name, _getInfo##in##out,                                          \
      63             :             CompressorReadDrawPixels::getNewCompressor,                       \
      64             :             CompressorReadDrawPixels::getNewDecompressor, 0,                  \
      65             :             CompressorReadDrawPixels::isCompatible));                         \
      66             :         _depths[name] = size;                                                 \
      67             :         return true;                                                          \
      68             :     }                                                                         \
      69             :                                                                               \
      70             :     static bool _initialized##in##out LB_UNUSED = _register##in##out();
      71             : 
      72          18 : REGISTER_TRANSFER(RGBA, RGBA, 4, 1., 1., 1., false);
      73          18 : REGISTER_TRANSFER(RGBA, BGRA, 4, 1., 1., 2., false);
      74          18 : REGISTER_TRANSFER(RGBA, RGBA_UINT_8_8_8_8_REV, 4, 1., 1., 1., false);
      75          18 : REGISTER_TRANSFER(RGBA, BGRA_UINT_8_8_8_8_REV, 4, 1., 1., 2., false);
      76          18 : REGISTER_TRANSFER(RGBA, RGB, 3, 1., 1., .7, true);
      77          18 : REGISTER_TRANSFER(RGBA, BGR, 3, 1., 1., .7, true);
      78             : 
      79          18 : REGISTER_TRANSFER(RGB10_A2, BGR10_A2, 4, 1., 1., 1.1, false);
      80          18 : REGISTER_TRANSFER(RGB10_A2, RGB10_A2, 4, 1., 1., 1., false);
      81             : 
      82          18 : REGISTER_TRANSFER(RGBA16F, RGBA16F, 8, 1., 1., 1., false);
      83          18 : REGISTER_TRANSFER(RGBA16F, BGRA16F, 8, 1., 1., 1.1, false);
      84          18 : REGISTER_TRANSFER(RGBA16F, RGB16F, 6, 1., 1., 1., true);
      85          18 : REGISTER_TRANSFER(RGBA16F, BGR16F, 6, 1., 1., 1.1, true);
      86          18 : REGISTER_TRANSFER(RGBA16F, RGBA, 4, .5, .5, 1., false);
      87          18 : REGISTER_TRANSFER(RGBA16F, BGRA, 4, .5, .5, 1.1, false);
      88          18 : REGISTER_TRANSFER(RGBA16F, RGB, 3, .5, .5, 1., true);
      89          18 : REGISTER_TRANSFER(RGBA16F, BGR, 3, .5, .5, 1.1, true);
      90             : 
      91          18 : REGISTER_TRANSFER(RGBA32F, RGBA32F, 16, 1., 1., 1.1, false);
      92          18 : REGISTER_TRANSFER(RGBA32F, BGRA32F, 16, 1., 1., 1., false);
      93          18 : REGISTER_TRANSFER(RGBA32F, RGB32F, 12, 1., 1., 1., true);
      94          18 : REGISTER_TRANSFER(RGBA32F, BGR32F, 12, 1., 1., 1.1, true);
      95          18 : REGISTER_TRANSFER(RGBA32F, RGBA16F, 8, .5, .5, 1., false);
      96          18 : REGISTER_TRANSFER(RGBA32F, BGRA16F, 8, .5, .5, 1.1, false);
      97          18 : REGISTER_TRANSFER(RGBA32F, RGB16F, 6, .5, .5, 1., true);
      98          18 : REGISTER_TRANSFER(RGBA32F, BGR16F, 6, .5, .5, 1.1, true);
      99          18 : REGISTER_TRANSFER(RGBA32F, RGBA, 4, .25, .25, 1., false);
     100          18 : REGISTER_TRANSFER(RGBA32F, BGRA, 4, .25, .25, 1.1, false);
     101          18 : REGISTER_TRANSFER(RGBA32F, RGB, 3, .25, .25, 1., true);
     102          18 : REGISTER_TRANSFER(RGBA32F, BGR, 3, .25, .25, 1.1, true);
     103             : 
     104          18 : REGISTER_TRANSFER(DEPTH, DEPTH_UNSIGNED_INT, 4, 1., 1., 1., false);
     105             : }
     106             : 
     107           4 : CompressorReadDrawPixels::CompressorReadDrawPixels(const unsigned name)
     108             :     : Compressor()
     109             :     , _texture(0)
     110             :     , _pbo(0)
     111             :     , _internalFormat(0)
     112             :     , _format(0)
     113             :     , _type(0)
     114           4 :     , _depth(_depths[name])
     115             : {
     116           4 :     LBASSERT(_depth > 0);
     117           4 :     switch (name)
     118             :     {
     119             :     case EQ_COMPRESSOR_TRANSFER_RGBA_TO_RGBA:
     120           0 :         _format = GL_RGBA;
     121           0 :         _type = GL_UNSIGNED_BYTE;
     122           0 :         _internalFormat = GL_RGBA;
     123           0 :         break;
     124             :     case EQ_COMPRESSOR_TRANSFER_RGBA_TO_RGBA_UINT_8_8_8_8_REV:
     125           0 :         _format = GL_RGBA;
     126           0 :         _type = GL_UNSIGNED_BYTE;
     127           0 :         _internalFormat = GL_RGBA;
     128           0 :         break;
     129             :     case EQ_COMPRESSOR_TRANSFER_RGBA16F_TO_RGBA:
     130           0 :         _format = GL_RGBA;
     131           0 :         _type = GL_UNSIGNED_BYTE;
     132           0 :         _internalFormat = GL_RGBA16F;
     133           0 :         break;
     134             :     case EQ_COMPRESSOR_TRANSFER_RGBA16F_TO_RGBA16F:
     135           0 :         _format = GL_RGBA;
     136           0 :         _type = GL_HALF_FLOAT;
     137           0 :         _internalFormat = GL_RGBA16F;
     138           0 :         break;
     139             :     case EQ_COMPRESSOR_TRANSFER_RGBA32F_TO_RGBA:
     140           0 :         _format = GL_RGBA;
     141           0 :         _type = GL_UNSIGNED_BYTE;
     142           0 :         _internalFormat = GL_RGBA32F;
     143           0 :         break;
     144             :     case EQ_COMPRESSOR_TRANSFER_RGBA32F_TO_RGBA16F:
     145           0 :         _format = GL_RGBA;
     146           0 :         _type = GL_HALF_FLOAT;
     147           0 :         _internalFormat = GL_RGBA32F;
     148           0 :         break;
     149             :     case EQ_COMPRESSOR_TRANSFER_RGBA32F_TO_RGBA32F:
     150           0 :         _format = GL_RGBA;
     151           0 :         _type = GL_FLOAT;
     152           0 :         _internalFormat = GL_RGBA32F;
     153           0 :         break;
     154             : 
     155             :     case EQ_COMPRESSOR_TRANSFER_RGBA_TO_BGRA:
     156           4 :         _format = GL_BGRA;
     157           4 :         _type = GL_UNSIGNED_BYTE;
     158           4 :         _internalFormat = GL_RGBA;
     159           4 :         break;
     160             :     case EQ_COMPRESSOR_TRANSFER_RGBA_TO_BGRA_UINT_8_8_8_8_REV:
     161           0 :         _format = GL_BGRA;
     162           0 :         _type = GL_UNSIGNED_BYTE;
     163           0 :         _internalFormat = GL_RGBA;
     164           0 :         break;
     165             :     case EQ_COMPRESSOR_TRANSFER_RGB10_A2_TO_BGR10_A2:
     166           0 :         _format = GL_BGRA;
     167           0 :         _type = GL_UNSIGNED_INT_10_10_10_2;
     168           0 :         _internalFormat = GL_RGB10_A2;
     169           0 :         break;
     170             :     case EQ_COMPRESSOR_TRANSFER_RGB10_A2_TO_RGB10_A2:
     171           0 :         _format = GL_RGBA;
     172           0 :         _type = GL_UNSIGNED_INT_10_10_10_2;
     173           0 :         _internalFormat = GL_RGB10_A2;
     174           0 :         break;
     175             :     case EQ_COMPRESSOR_TRANSFER_RGBA16F_TO_BGRA:
     176           0 :         _format = GL_BGRA;
     177           0 :         _type = GL_UNSIGNED_BYTE;
     178           0 :         _internalFormat = GL_RGBA16F;
     179           0 :         break;
     180             :     case EQ_COMPRESSOR_TRANSFER_RGBA16F_TO_BGRA16F:
     181           0 :         _format = GL_BGRA;
     182           0 :         _type = GL_HALF_FLOAT;
     183           0 :         _internalFormat = GL_RGBA16F;
     184           0 :         break;
     185             :     case EQ_COMPRESSOR_TRANSFER_RGBA32F_TO_BGRA:
     186           0 :         _format = GL_BGRA;
     187           0 :         _type = GL_UNSIGNED_BYTE;
     188           0 :         _internalFormat = GL_RGBA32F;
     189           0 :         break;
     190             :     case EQ_COMPRESSOR_TRANSFER_RGBA32F_TO_BGRA16F:
     191           0 :         _format = GL_BGRA;
     192           0 :         _type = GL_HALF_FLOAT;
     193           0 :         _internalFormat = GL_RGBA32F;
     194           0 :         break;
     195             :     case EQ_COMPRESSOR_TRANSFER_RGBA32F_TO_BGRA32F:
     196           0 :         _format = GL_BGRA;
     197           0 :         _type = GL_FLOAT;
     198           0 :         _internalFormat = GL_RGBA32F;
     199           0 :         break;
     200             :     case EQ_COMPRESSOR_TRANSFER_RGBA_TO_RGB:
     201           0 :         _format = GL_RGB;
     202           0 :         _type = GL_UNSIGNED_BYTE;
     203           0 :         _internalFormat = GL_RGBA;
     204           0 :         break;
     205             :     case EQ_COMPRESSOR_TRANSFER_RGBA16F_TO_RGB:
     206           0 :         _format = GL_RGB;
     207           0 :         _type = GL_UNSIGNED_BYTE;
     208           0 :         _internalFormat = GL_RGBA16F;
     209           0 :         break;
     210             :     case EQ_COMPRESSOR_TRANSFER_RGBA16F_TO_RGB16F:
     211           0 :         _format = GL_RGB;
     212           0 :         _type = GL_HALF_FLOAT;
     213           0 :         _internalFormat = GL_RGBA16F;
     214           0 :         break;
     215             :     case EQ_COMPRESSOR_TRANSFER_RGBA32F_TO_RGB:
     216           0 :         _format = GL_RGB;
     217           0 :         _type = GL_UNSIGNED_BYTE;
     218           0 :         _internalFormat = GL_RGBA32F;
     219           0 :         break;
     220             :     case EQ_COMPRESSOR_TRANSFER_RGBA32F_TO_RGB32F:
     221           0 :         _format = GL_RGB;
     222           0 :         _type = GL_FLOAT;
     223           0 :         _internalFormat = GL_RGBA32F;
     224           0 :         break;
     225             :     case EQ_COMPRESSOR_TRANSFER_RGBA32F_TO_RGB16F:
     226           0 :         _format = GL_RGB;
     227           0 :         _type = GL_HALF_FLOAT;
     228           0 :         _internalFormat = GL_RGBA32F;
     229           0 :         break;
     230             :     case EQ_COMPRESSOR_TRANSFER_RGBA_TO_BGR:
     231           0 :         _format = GL_BGR;
     232           0 :         _type = GL_UNSIGNED_BYTE;
     233           0 :         _internalFormat = GL_RGBA;
     234           0 :         break;
     235             :     case EQ_COMPRESSOR_TRANSFER_RGBA16F_TO_BGR:
     236           0 :         _format = GL_BGR;
     237           0 :         _type = GL_UNSIGNED_BYTE;
     238           0 :         _internalFormat = GL_RGBA16F;
     239           0 :         break;
     240             :     case EQ_COMPRESSOR_TRANSFER_RGBA16F_TO_BGR16F:
     241           0 :         _format = GL_BGR;
     242           0 :         _type = GL_HALF_FLOAT;
     243           0 :         _internalFormat = GL_RGBA16F;
     244           0 :         break;
     245             :     case EQ_COMPRESSOR_TRANSFER_RGBA32F_TO_BGR:
     246           0 :         _format = GL_BGR;
     247           0 :         _type = GL_UNSIGNED_BYTE;
     248           0 :         _internalFormat = GL_RGBA32F;
     249           0 :         break;
     250             :     case EQ_COMPRESSOR_TRANSFER_RGBA32F_TO_BGR32F:
     251           0 :         _format = GL_BGR;
     252           0 :         _type = GL_FLOAT;
     253           0 :         _internalFormat = GL_RGBA32F;
     254           0 :         break;
     255             :     case EQ_COMPRESSOR_TRANSFER_RGBA32F_TO_BGR16F:
     256           0 :         _format = GL_BGR;
     257           0 :         _type = GL_HALF_FLOAT;
     258           0 :         _internalFormat = GL_RGBA32F;
     259           0 :         break;
     260             :     case EQ_COMPRESSOR_TRANSFER_DEPTH_TO_DEPTH_UNSIGNED_INT:
     261           0 :         _format = GL_DEPTH_COMPONENT;
     262           0 :         _type = GL_UNSIGNED_INT;
     263           0 :         _internalFormat = GL_DEPTH_COMPONENT;
     264           0 :         break;
     265             : 
     266             :     default:
     267           0 :         LBASSERT(false);
     268             :     }
     269           4 : }
     270             : 
     271          12 : CompressorReadDrawPixels::~CompressorReadDrawPixels()
     272             : {
     273           4 :     delete _texture;
     274           4 :     _texture = 0;
     275             : 
     276           4 :     if (_pbo)
     277             :     {
     278           2 :         _pbo->destroy();
     279           2 :         delete _pbo;
     280           2 :         _pbo = 0;
     281             :     }
     282           8 : }
     283             : 
     284          16 : bool CompressorReadDrawPixels::isCompatible(const GLEWContext*)
     285             : {
     286          16 :     return true;
     287             : }
     288             : 
     289             : namespace
     290             : {
     291           2 : void _copy4(eq_uint64_t dst[4], const eq_uint64_t src[4])
     292             : {
     293           2 :     memcpy(&dst[0], &src[0], sizeof(eq_uint64_t) * 4);
     294           2 : }
     295             : 
     296           4 : void _initPackAlignment(const eq_uint64_t width)
     297             : {
     298           4 :     if ((width % 4) == 0)
     299             :     {
     300           0 :         EQ_GL_CALL(glPixelStorei(GL_PACK_ALIGNMENT, 4));
     301             :     }
     302           4 :     else if ((width % 2) == 0)
     303             :     {
     304           4 :         EQ_GL_CALL(glPixelStorei(GL_PACK_ALIGNMENT, 2));
     305             :     }
     306             :     else
     307             :     {
     308           0 :         EQ_GL_CALL(glPixelStorei(GL_PACK_ALIGNMENT, 1));
     309             :     }
     310           4 : }
     311             : 
     312           2 : void _initUnpackAlignment(const eq_uint64_t width)
     313             : {
     314           2 :     if ((width % 4) == 0)
     315             :     {
     316           0 :         EQ_GL_CALL(glPixelStorei(GL_UNPACK_ALIGNMENT, 4));
     317             :     }
     318           2 :     else if ((width % 2) == 0)
     319             :     {
     320           2 :         EQ_GL_CALL(glPixelStorei(GL_UNPACK_ALIGNMENT, 2));
     321             :     }
     322             :     else
     323             :     {
     324           0 :         EQ_GL_CALL(glPixelStorei(GL_UNPACK_ALIGNMENT, 1));
     325             :     }
     326           2 : }
     327             : }
     328             : 
     329           2 : void CompressorReadDrawPixels::_resizeBuffer(const eq_uint64_t size)
     330             : {
     331             : // eile: The code path using realloc creates visual artefacts on my MacBook
     332             : //       The other crashes occasionally with KERN_BAD_ADDRESS
     333             : //       Seems to be only with GL_RGB. Radar #8261726.
     334             : #if 1
     335           2 :     _buffer.reserve(size);
     336           2 :     _buffer.setSize(size);
     337             : #else
     338             :     // eile: This code path using realloc creates visual artefacts on my MacBook
     339             :     _buffer.resize(size);
     340             : #endif
     341           2 : }
     342             : 
     343           0 : void CompressorReadDrawPixels::_initDownload(const GLEWContext*,
     344             :                                              const eq_uint64_t inDims[4],
     345             :                                              eq_uint64_t outDims[4])
     346             : {
     347           0 :     _copy4(outDims, inDims);
     348           0 :     const size_t size = inDims[1] * inDims[3] * _depth;
     349           0 :     _resizeBuffer(size);
     350           0 :     _initPackAlignment(outDims[1]);
     351           0 : }
     352             : 
     353           0 : void CompressorReadDrawPixels::_initTexture(const GLEWContext* glewContext,
     354             :                                             const eq_uint64_t flags)
     355             : {
     356           0 :     GLenum target = 0;
     357           0 :     if (flags & EQ_COMPRESSOR_USE_TEXTURE_2D)
     358           0 :         target = GL_TEXTURE_2D;
     359           0 :     else if (flags & EQ_COMPRESSOR_USE_TEXTURE_RECT)
     360           0 :         target = GL_TEXTURE_RECTANGLE_ARB;
     361             :     else
     362             :     {
     363           0 :         LBUNREACHABLE;
     364             :     }
     365             : 
     366           0 :     if (!_texture || _texture->getTarget() != target)
     367             :     {
     368           0 :         delete _texture;
     369           0 :         _texture = new util::Texture(target, glewContext);
     370             :     }
     371           0 : }
     372             : 
     373           0 : void CompressorReadDrawPixels::_initAsyncTexture(const GLEWContext* glewContext,
     374             :                                                  const eq_uint64_t w,
     375             :                                                  const eq_uint64_t h)
     376             : {
     377           0 :     if (!_texture || _texture->getTarget() != GL_TEXTURE_RECTANGLE_ARB ||
     378           0 :         !_texture->isValid())
     379             :     {
     380           0 :         delete _texture;
     381           0 :         _texture = new util::Texture(GL_TEXTURE_RECTANGLE_ARB, glewContext);
     382             :     }
     383             : 
     384           0 :     _texture->setGLEWContext(glewContext);
     385           0 :     _texture->init(_internalFormat, w, h);
     386             : 
     387             :     // ensure texture exists in tfer thread, might need fence for Tesla GPUs
     388           0 :     glFlush();
     389           0 : }
     390             : 
     391           0 : void CompressorReadDrawPixels::download(const GLEWContext* glewContext,
     392             :                                         const eq_uint64_t inDims[4],
     393             :                                         const unsigned source,
     394             :                                         const eq_uint64_t flags,
     395             :                                         eq_uint64_t outDims[4], void** out)
     396             : {
     397           0 :     _initDownload(glewContext, inDims, outDims);
     398             : 
     399           0 :     if (flags & EQ_COMPRESSOR_USE_FRAMEBUFFER)
     400             :     {
     401           0 :         EQ_GL_CALL(glReadPixels(inDims[0], inDims[2], inDims[1], inDims[3],
     402             :                                 _format, _type, _buffer.getData()));
     403           0 :         *out = _buffer.getData();
     404             :     }
     405             :     else
     406             :     {
     407           0 :         _initTexture(glewContext, flags);
     408           0 :         _texture->setGLData(source, _internalFormat, inDims[1], inDims[3]);
     409           0 :         _texture->setExternalFormat(_format, _type);
     410           0 :         *out = _downloadTexture(glewContext, FLUSH_TEXTURE);
     411             :     }
     412           0 : }
     413             : 
     414           2 : void CompressorReadDrawPixels::upload(const GLEWContext* glewContext,
     415             :                                       const void* buffer,
     416             :                                       const eq_uint64_t inDims[4],
     417             :                                       const eq_uint64_t flags,
     418             :                                       const eq_uint64_t outDims[4],
     419             :                                       const unsigned destination)
     420             : {
     421           2 :     _initUnpackAlignment(inDims[1]);
     422             : 
     423           2 :     if (flags & EQ_COMPRESSOR_USE_FRAMEBUFFER)
     424             :     {
     425           2 :         EQ_GL_CALL(glRasterPos2i(outDims[0], outDims[2]));
     426           2 :         EQ_GL_CALL(
     427             :             glDrawPixels(outDims[1], outDims[3], _format, _type, buffer));
     428             :     }
     429             :     else
     430             :     {
     431           0 :         LBASSERT(outDims[0] == 0 && outDims[2] == 0); // Implement me
     432           0 :         _initTexture(glewContext, flags);
     433           0 :         _texture->setGLData(destination, _internalFormat, outDims[1],
     434           0 :                             outDims[3]);
     435           0 :         _texture->setExternalFormat(_format, _type);
     436           0 :         _texture->upload(outDims[1], outDims[3], buffer);
     437           0 :         _texture->flushNoDelete();
     438             :     }
     439           2 : }
     440             : 
     441           2 : bool CompressorReadDrawPixels::_initPBO(const GLEWContext* glewContext,
     442             :                                         const eq_uint64_t size)
     443             : {
     444           2 :     if (!_pbo)
     445           2 :         _pbo = new util::PixelBufferObject(glewContext);
     446             : 
     447           2 :     const Error error = _pbo->setup(size, GL_READ_ONLY_ARB);
     448           2 :     if (!error)
     449           2 :         return true;
     450             : 
     451           0 :     if (_warned < 10)
     452             :     {
     453           0 :         LBWARN << "Can't initialize PBO for async readback: " << error
     454           0 :                << std::endl;
     455           0 :         ++_warned;
     456             :     }
     457           0 :     return false;
     458             : }
     459             : 
     460           2 : void CompressorReadDrawPixels::startDownload(const GLEWContext* glewContext,
     461             :                                              const eq_uint64_t dims[4],
     462             :                                              const unsigned source,
     463             :                                              const eq_uint64_t flags)
     464             : {
     465           2 :     _initPackAlignment(dims[1]);
     466             : 
     467           2 :     const eq_uint64_t size = dims[1] * dims[3] * _depth;
     468           2 :     if (flags & EQ_COMPRESSOR_USE_FRAMEBUFFER)
     469             :     {
     470             :         // async RB through texture
     471           2 :         if (!GLEW_ARB_pixel_buffer_object)
     472             :         {
     473           0 :             const PixelViewport pvp(dims[0], dims[2], dims[1], dims[3]);
     474           0 :             _initAsyncTexture(glewContext, pvp.w, pvp.h);
     475           0 :             _texture->setExternalFormat(_format, _type);
     476           0 :             _texture->copyFromFrameBuffer(_internalFormat, pvp);
     477           0 :             _resizeBuffer(size);
     478           0 :             return;
     479             :         }
     480             : 
     481           2 :         if (_initPBO(glewContext, size))
     482             :         {
     483           2 :             EQ_GL_CALL(glReadPixels(dims[0], dims[2], dims[1], dims[3], _format,
     484             :                                     _type, 0));
     485           2 :             _pbo->unbind();
     486           2 :             glFlush(); // Fixes https://github.com/Eyescale/Equalizer/issues/118
     487           2 :             return;
     488             :         }
     489             :         // else
     490           0 :         _resizeBuffer(size);
     491           0 :         EQ_GL_CALL(glReadPixels(dims[0], dims[2], dims[1], dims[3], _format,
     492             :                                 _type, _buffer.getData()));
     493             :     }
     494             :     else
     495             :     {
     496           0 :         _resizeBuffer(size);
     497           0 :         _initTexture(glewContext, flags);
     498           0 :         _texture->setGLData(source, _internalFormat, dims[1], dims[3]);
     499           0 :         _texture->setExternalFormat(_format, _type);
     500           0 :         glFlush(); // Enough?
     501             :     }
     502             : }
     503             : 
     504           0 : void* CompressorReadDrawPixels::_downloadTexture(const GLEWContext* glewContext,
     505             :                                                  const FlushMode mode)
     506             : {
     507           0 :     LBASSERT(_texture);
     508           0 :     _texture->setGLEWContext(glewContext);
     509           0 :     _texture->download(_buffer.getData());
     510           0 :     if (mode == FLUSH_TEXTURE)
     511           0 :         _texture->flushNoDelete();
     512             : 
     513           0 :     return _buffer.getData();
     514             : }
     515             : 
     516           2 : void CompressorReadDrawPixels::finishDownload(const GLEWContext* glewContext,
     517             :                                               const eq_uint64_t inDims[4],
     518             :                                               const eq_uint64_t flags,
     519             :                                               eq_uint64_t outDims[4],
     520             :                                               void** out)
     521             : {
     522           2 :     _copy4(outDims, inDims);
     523           2 :     _initPackAlignment(inDims[1]);
     524             : 
     525           2 :     if (flags & (EQ_COMPRESSOR_USE_TEXTURE_RECT | EQ_COMPRESSOR_USE_TEXTURE_2D))
     526             :     {
     527           0 :         *out = _downloadTexture(glewContext, FLUSH_TEXTURE);
     528           0 :         return;
     529             :     }
     530             : 
     531           2 :     LBASSERT(flags & EQ_COMPRESSOR_USE_FRAMEBUFFER);
     532             : 
     533             :     // async RB through texture
     534           2 :     if (!GLEW_ARB_pixel_buffer_object)
     535             :     {
     536           0 :         *out = _downloadTexture(glewContext, KEEP_TEXTURE);
     537           0 :         return;
     538             :     }
     539             : 
     540           2 :     if (_pbo && _pbo->isInitialized())
     541             :     {
     542           2 :         const eq_uint64_t size = inDims[1] * inDims[3] * _depth;
     543           2 :         _resizeBuffer(size);
     544             : 
     545           2 :         const void* ptr = _pbo->mapRead();
     546           2 :         if (ptr)
     547             :         {
     548           2 :             memcpy(_buffer.getData(), ptr, size);
     549           2 :             _pbo->unmap();
     550             :         }
     551             :         else
     552             :         {
     553           0 :             LBERROR << "Can't map PBO" << std::endl;
     554           0 :             EQ_GL_ERROR("PixelBufferObject::mapRead()");
     555             :         }
     556             :     }
     557           2 :     *out = _buffer.getData();
     558             : }
     559             : }
     560          18 : }

Generated by: LCOV version 1.11