Equalizer  1.8.0
Parallel Rendering Framework
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Pages
eqPixelBench/channel.cpp
1 
2 /* Copyright (c) 2007-2013, Stefan Eilemann <eile@equalizergraphics.com>
3  * 2012, Daniel Nachbaur <danielnachbaur@gmail.com>
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions are met:
7  *
8  * - Redistributions of source code must retain the above copyright notice, this
9  * list of conditions and the following disclaimer.
10  * - Redistributions in binary form must reproduce the above copyright notice,
11  * this list of conditions and the following disclaimer in the documentation
12  * and/or other materials provided with the distribution.
13  * - Neither the name of Eyescale Software GmbH nor the names of its
14  * contributors may be used to endorse or promote products derived from this
15  * software without specific prior written permission.
16  *
17  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
18  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
21  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
22  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
23  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
24  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
25  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
26  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
27  * POSSIBILITY OF SUCH DAMAGE.
28  */
29 
30 #include "channel.h"
31 
32 #include "config.h"
33 #include "configEvent.h"
34 
35 #ifdef WIN32_API
36 # define snprintf _snprintf
37 #endif
38 
39 namespace eqPixelBench
40 {
41 namespace
42 {
43 #pragma warning(disable: 411) // class defines no constructor to initialize ...
44 struct EnumMap
45 {
46  const char* internalFormatString;
47  const uint32_t internalFormat;
48  const size_t pixelSize;
49 };
50 
51 #pragma warning(default: 411)
52 
53 #define ENUM_MAP_ITEM( internalFormat, pixelSize ) \
54  { #internalFormat, EQ_COMPRESSOR_DATATYPE_ ## internalFormat, pixelSize }
55 
56 static EnumMap _enums[] = {
57  ENUM_MAP_ITEM( RGBA32F, 16 ), // initial buffer resize
58  ENUM_MAP_ITEM( RGBA, 4 ),
59  ENUM_MAP_ITEM( RGB10_A2, 4 ),
60  ENUM_MAP_ITEM( RGBA16F, 8 ),
61  ENUM_MAP_ITEM( RGBA32F, 16 ),
62  ENUM_MAP_ITEM( DEPTH, 4 ),
63  { 0, 0, 0 }};
64 #define NUM_IMAGES 8
65 }
66 
67 Channel::Channel( eq::Window* parent )
68  : eq::Channel( parent )
69 {
70  eq::FrameDataPtr frameData = new eq::FrameData;
71  _frame.setFrameData( frameData );
72 
73  for( unsigned i = 0; i < NUM_IMAGES; ++i )
74  frameData->newImage( eq::Frame::TYPE_MEMORY, getDrawableConfig( ));
75 }
76 
78 {
79  _frame.getFrameData()->resetPlugins();
80  return eq::Channel::configExit();
81 }
82 
83 void Channel::frameStart( const eq::uint128_t& frameID,
84  const uint32_t frameNumber )
85 {
86  Config* config = static_cast< Config* >( getConfig( ));
87  const lunchbox::Clock* clock = config->getClock();
88 
89  if( clock )
90  {
91  const std::string formatType = "app->pipe thread latency";
92  _sendEvent( START_LATENCY, clock->getTimef(), eq::Vector2i( 0, 0 ),
93  formatType, 0, 0 );
94  }
95 
96  eq::Channel::frameStart( frameID, frameNumber );
97 }
98 
99 void Channel::frameDraw( const eq::uint128_t& )
100 {
101  //----- setup GL state
102  applyBuffer();
103  applyViewport();
104 
105  glMatrixMode( GL_PROJECTION );
106  glLoadIdentity();
107 
108  applyFrustum();
109 
110  glMatrixMode( GL_MODELVIEW );
111  glLoadIdentity();
113 
115 
116  _testFormats( 1.0f );
117  _testFormats( 0.5f );
118  _testFormats( 2.0f );
119  _testTiledOperations();
120  _testDepthAssemble();
121 
123 }
124 
125 void Channel::_testFormats( float applyZoom )
126 {
127  glGetError(); // reset
128 
129  //----- setup constant data
130  const eq::Images& images = _frame.getImages();
131  eq::Image* image = images[ 0 ];
132  LBASSERT( image );
133 
134  const eq::PixelViewport& pvp = getPixelViewport();
135  const eq::Vector2i offset( pvp.x, pvp.y );
136  const eq::Zoom zoom( applyZoom, applyZoom );
137 
138  lunchbox::Clock clock;
140 
141  //----- test all default format/type combinations
142  for( uint32_t i=0; _enums[i].internalFormatString; ++i )
143  {
144  const uint32_t internalFormat = _enums[i].internalFormat;
145  image->flush();
146  image->setInternalFormat( eq::Frame::BUFFER_COLOR, internalFormat );
147  image->setQuality( eq::Frame::BUFFER_COLOR, 0.f );
148  image->setAlphaUsage( false );
149 
150  const GLEWContext* glewContext = glewGetContext();
151  const std::vector< uint32_t >& names =
152  image->findTransferers( eq::Frame::BUFFER_COLOR, glewContext );
153 
154  for( std::vector< uint32_t >::const_iterator j = names.begin();
155  j != names.end(); ++j )
156  {
157  _draw( co::uint128_t( ));
158 
159  image->allocDownloader( eq::Frame::BUFFER_COLOR, *j, glewContext );
160  image->setPixelViewport( pvp );
161 
162  const uint32_t outputToken =
164  std::stringstream formatType;
165  formatType << std::hex << *j << ':'
166  << _enums[i].internalFormatString << '/' << outputToken
167  << std::dec;
168  // read
169  glFinish();
170  size_t nLoops = 0;
171  try
172  {
173  clock.reset();
174  while( clock.getTime64() < 100 /*ms*/ )
175  {
176  image->startReadback( eq::Frame::BUFFER_COLOR, pvp, zoom,
177  glObjects );
178  image->finishReadback( glObjects.glewGetContext( ));
179  ++nLoops;
180  }
181  glFinish();
182  const float msec = clock.getTimef() / float( nLoops );
183  const GLenum error = glGetError(); // release mode
184  if( error != GL_NO_ERROR )
185  throw eq::GLException( error );
186 
187  const eq::PixelData& pixels =
189  const eq::Vector2i area( pixels.pvp.w, pixels.pvp.h );
190  const uint64_t dataSizeGPU = area.x() * area.y() *
191  _enums[i].pixelSize;
192  const uint64_t dataSizeCPU =
194 
195  _sendEvent( READBACK, msec, area, formatType.str(), dataSizeGPU,
196  dataSizeCPU );
197  }
198  catch( const eq::GLException& e )
199  {
200  _sendEvent( READBACK, -static_cast<float>( e.glError ),
201  eq::Vector2i(), formatType.str(), 0, 0 );
202  continue;
203  }
204 
205  // write
207  op.channel = this;
209  op.offset = offset;
210  op.zoom = zoom;
211 
212  const uint64_t dataSizeCPU =
214  try
215  {
216  clock.reset();
217  eq::Compositor::assembleImage( image, op );
218  glFinish();
219  const float msec = clock.getTimef() / float( nLoops );
220  const GLenum error = glGetError(); // release mode
221  if( error != GL_NO_ERROR )
222  throw eq::Exception( error );
223 
224  const eq::PixelData& pixels =
226  const eq::Vector2i area( pixels.pvp.w, pixels.pvp.h );
227  const uint64_t dataSizeGPU =
229  _sendEvent( ASSEMBLE, msec, area, formatType.str(), dataSizeGPU,
230  dataSizeCPU );
231  }
232  catch( const eq::GLException& e ) // debug mode
233  {
234  _sendEvent( ASSEMBLE, -static_cast<float>( e.glError ),
235  eq::Vector2i(), formatType.str(), 0, 0 );
236  }
237  }
238  }
239 }
240 
241 void Channel::_testTiledOperations()
242 {
243  glGetError(); // reset
244 
245  //----- setup constant data
246  const eq::Images& images = _frame.getImages();
247  LBASSERT( images[0] );
248 
249  const eq::PixelViewport& pvp = getPixelViewport();
250  const eq::Vector2i offset( pvp.x, pvp.y );
251 
252  eq::Vector2i area;
253  area.x() = pvp.w;
254 
255  lunchbox::Clock clock;
257  const GLEWContext* glewContext = glewGetContext();
258 
259  //----- test tiled assembly algorithms
260  eq::PixelViewport subPVP = pvp;
261  subPVP.h /= NUM_IMAGES;
262 
263  for( unsigned i = 0; i < NUM_IMAGES; ++i )
264  {
265  LBASSERT( images[ i ] );
266  images[ i ]->setPixelViewport( subPVP );
267  }
268 
269  for( unsigned tiles = 0; tiles < NUM_IMAGES; ++tiles )
270  {
271  EQ_GL_CALL( _draw( co::uint128_t( )));
272  area.y() = subPVP.h * (tiles+1);
273 
274  //---- readback of 'tiles' depth images
275  std::stringstream formatType;
276  formatType << tiles+1 << " depth tiles";
277 
278  float msec = 0;
279  for( unsigned j = 0; j <= tiles; ++j )
280  {
281  subPVP.y = pvp.y + j * subPVP.h;
282  eq::Image* image = images[ j ];
283  LBCHECK( image->allocDownloader( eq::Frame::BUFFER_DEPTH,
284  EQ_COMPRESSOR_TRANSFER_DEPTH_TO_DEPTH_UNSIGNED_INT,
285  glewContext ));
287 
288  clock.reset();
289  image->startReadback( eq::Frame::BUFFER_DEPTH, subPVP,
290  eq::Zoom::NONE, glObjects );
291  image->finishReadback( glObjects.glewGetContext( ));
292  msec += clock.getTimef();
293  }
294 
295  _sendEvent( READBACK, msec, area, formatType.str(), 0, 0 );
296 
297  if( tiles == NUM_IMAGES-1 )
298  for( unsigned j = 0; j <= tiles; ++j )
299  _saveImage( images[j],
300  "EQ_COMPRESSOR_DATATYPE_DEPTH_UNSIGNED_INT",
301  "tiles" );
302 
303  //---- readback of 'tiles' color images
304  formatType.str("");
305  formatType << tiles+1 << " color tiles";
306 
307  msec = 0;
308  for( unsigned j = 0; j <= tiles; ++j )
309  {
310  subPVP.y = pvp.y + j * subPVP.h;
311  eq::Image* image = images[ j ];
312 
313  LBCHECK( image->allocDownloader( eq::Frame::BUFFER_COLOR,
314  EQ_COMPRESSOR_TRANSFER_RGBA_TO_BGRA,
315  glewContext ));
317 
318  clock.reset();
319  image->startReadback( eq::Frame::BUFFER_COLOR, subPVP,
320  eq::Zoom::NONE, glObjects );
321  image->finishReadback( glObjects.glewGetContext( ));
322  msec += clock.getTimef();
323  }
324  _sendEvent( READBACK, msec, area, formatType.str(), 0, 0 );
325 
326  if( tiles == NUM_IMAGES-1 )
327  for( unsigned j = 0; j <= tiles; ++j )
328  _saveImage( images[j],"EQ_COMPRESSOR_DATATYPE_BGRA","tiles" );
329 
330  //---- benchmark assembly operations
331  subPVP.y = pvp.y + tiles * subPVP.h;
332 
334  op.channel = this;
336  op.offset = offset;
337 
338  // fixed-function
339  formatType.str("");
340  formatType << "tiles, GL1.1, " << tiles+1 << " images";
341 
342  clock.reset();
343  for( unsigned j = 0; j <= tiles; ++j )
344  eq::Compositor::assembleImage( images[j], op );
345 
346  msec = clock.getTimef();
347  _sendEvent( ASSEMBLE, msec, area, formatType.str(), 0, 0 );
348 
349  // CPU
350  formatType.str("");
351  formatType << "tiles, CPU, " << tiles+1 << " images";
352 
353  std::vector< eq::Frame* > frames;
354  frames.push_back( &_frame );
355 
356  clock.reset();
357  eq::Compositor::assembleFramesCPU( frames, this );
358  msec = clock.getTimef();
359  _sendEvent( ASSEMBLE, msec, area, formatType.str(), 0, 0 );
360  }
361 }
362 
363 void Channel::_testDepthAssemble()
364 {
365  glGetError(); // reset
366 
367  //----- setup constant data
368  const eq::Images& images = _frame.getImages();
369  eq::Image* image = images[ 0 ];
370  LBASSERT( image );
371 
372  const eq::PixelViewport& pvp = getPixelViewport();
373  const eq::Vector2i offset( pvp.x, pvp.y );
374 
375  eq::Vector2i area;
376  area.x() = pvp.w;
377 
378  lunchbox::Clock clock;
380  const GLEWContext* glewContext = glewGetContext();
381 
382  //----- test depth-based assembly algorithms
383  for( unsigned i = 0; i < NUM_IMAGES; ++i )
384  {
385  image = images[ i ];
386  LBASSERT( image );
387  image->setPixelViewport( pvp );
388  }
389 
390  area.y() = pvp.h;
391 
392  for( uint64_t i = 0; i < NUM_IMAGES; ++i )
393  {
394  _draw( co::uint128_t( i ) );
395 
396  // fill depth & color image
397  image = images[ i ];
398 
399  LBCHECK( image->allocDownloader( eq::Frame::BUFFER_COLOR,
400  EQ_COMPRESSOR_TRANSFER_RGBA_TO_BGRA,
401  glewContext ));
402 
403  LBCHECK( image->allocDownloader( eq::Frame::BUFFER_DEPTH,
404  EQ_COMPRESSOR_TRANSFER_DEPTH_TO_DEPTH_UNSIGNED_INT,
405  glewContext ));
406 
409 
411  pvp, eq::Zoom::NONE, glObjects );
412  image->finishReadback( glObjects.glewGetContext( ));
413  LBASSERT( image->hasPixelData( eq::Frame::BUFFER_COLOR ));
414  LBASSERT( image->hasPixelData( eq::Frame::BUFFER_DEPTH ));
415 
416  if( i == NUM_IMAGES-1 )
417  _saveImage( image,"EQ_COMPRESSOR_DATATYPE_DEPTH_UNSIGNED_INT",
418  "depthAssemble" );
419 
420  // benchmark
422  op.channel = this;
424  op.offset = offset;
425 
426  // fixed-function
427  std::stringstream formatType;
428  formatType << "depth, GL1.1, " << i+1 << " images";
429 
430  clock.reset();
431  for( unsigned j = 0; j <= i; ++j )
432  eq::Compositor::assembleImageDB_FF( images[j], op );
433 
434  float msec = clock.getTimef();
435  _sendEvent( ASSEMBLE, msec, area, formatType.str(), 0, 0 );
436 
437  // GLSL
438  if( GLEW_VERSION_2_0 )
439  {
440  formatType.str("");
441  formatType << "depth, GLSL, " << i+1 << " images";
442 
443  clock.reset();
444  for( unsigned j = 0; j <= i; ++j )
445  eq::Compositor::assembleImageDB_GLSL( images[j], op );
446  msec = clock.getTimef();
447  _sendEvent( ASSEMBLE, msec, area, formatType.str(), 0, 0 );
448  }
449 
450  // CPU
451  formatType.str("");
452  formatType << "depth, CPU, " << i+1 << " images";
453 
454  std::vector< eq::Frame* > frames;
455  frames.push_back( &_frame );
456 
457  clock.reset();
458  eq::Compositor::assembleFramesCPU( frames, this );
459  msec = clock.getTimef();
460  _sendEvent( ASSEMBLE, msec, area, formatType.str(), 0, 0 );
461  }
462 }
463 
464 void Channel::_sendEvent( ConfigEventType type, const float msec,
465  const eq::Vector2i& area,
466  const std::string& formatType,
467  const uint64_t dataSizeGPU,
468  const uint64_t dataSizeCPU )
469 {
470  std::string name = getName();
471  if( name.empty( ))
472  {
473  std::stringstream strName;
474  strName << this;
475  name = strName.str();
476  }
477 
478  getConfig()->sendEvent( type )
479  << msec << name << area << formatType << dataSizeGPU << dataSizeCPU;
480 }
481 
482 void Channel::_saveImage( const eq::Image* image,
483  const char* externalformat,
484  const char* info )
485 {
486  return;
487 
488  static uint32_t counter = 0;
489  std::ostringstream stringstream;
490  stringstream << "Image_" << ++counter << "_" << externalformat << "_"
491  << info;
492  image->writeImages( stringstream.str( ));
493 }
494 
495 void Channel::_draw( const eq::uint128_t& spin )
496 {
497  bindFrameBuffer();
498  EQ_GL_CALL( glPushAttrib( GL_ALL_ATTRIB_BITS ));
499 
500  eq::Channel::frameDraw( spin );
501  EQ_GL_CALL( glClear( GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT ));
502  EQ_GL_CALL( glEnable( GL_DEPTH_TEST ));
503 
504  const float lightPos[] = { 0.0f, 0.0f, 1.0f, 0.0f };
505  glLightfv( GL_LIGHT0, GL_POSITION, lightPos );
506 
507  const float lightAmbient[] = { 0.2f, 0.2f, 0.2f, 1.0f };
508  glLightfv( GL_LIGHT0, GL_AMBIENT, lightAmbient );
509 
510  // rotate scene around the origin
511  glRotatef( static_cast< float >( spin.low() + 3 ) * 10, 1.0f, 0.5f, 0.25f );
512 
513  // render six axis-aligned colored quads around the origin
514  // front
515  glColor3f( 1.0f, 0.5f, 0.5f );
516  glNormal3f( 0.0f, 0.0f, 1.0f );
517  glBegin( GL_TRIANGLE_STRIP );
518  glVertex3f( .7f, .7f, -1.0f );
519  glVertex3f( -.7f, .7f, -1.0f );
520  glVertex3f( .7f, -.7f, -1.0f );
521  glVertex3f( -.7f, -.7f, -1.0f );
522  glEnd();
523 
524  // bottom
525  glColor3f( 0.5f, 1.0f, 0.5f );
526  glNormal3f( 0.0f, 1.0f, 0.0f );
527  glBegin( GL_TRIANGLE_STRIP );
528  glVertex3f( .7f, -1.0f, .7f );
529  glVertex3f( -.7f, -1.0f, .7f );
530  glVertex3f( .7f, -1.0f, -.7f );
531  glVertex3f( -.7f, -1.0f, -.7f );
532  glEnd();
533 
534  // back
535  glColor3f( 0.5f, 0.5f, 1.0f );
536  glNormal3f( 0.0f, 0.0f, -1.0f );
537  glBegin( GL_TRIANGLE_STRIP );
538  glVertex3f( .7f, .7f, 1.0f );
539  glVertex3f( -.7f, .7f, 1.0f );
540  glVertex3f( .7f, -.7f, 1.0f );
541  glVertex3f( -.7f, -.7f, 1.0f );
542  glEnd();
543 
544  // top
545  glColor3f( 1.0f, 1.0f, 0.5f );
546  glNormal3f( 0.f, -1.f, 0.f );
547  glBegin( GL_TRIANGLE_STRIP );
548  glVertex3f( .7f, 1.0f, .7f );
549  glVertex3f( -.7f, 1.0f, .7f );
550  glVertex3f( .7f, 1.0f, -.7f );
551  glVertex3f( -.7f, 1.0f, -.7f );
552  glEnd();
553 
554  // right
555  glColor3f( 1.0f, 0.5f, 1.0f );
556  glNormal3f( -1.f, 0.f, 0.f );
557  glBegin( GL_TRIANGLE_STRIP );
558  glVertex3f( 1.0f, .7f, .7f );
559  glVertex3f( 1.0f, -.7f, .7f );
560  glVertex3f( 1.0f, .7f, -.7f );
561  glVertex3f( 1.0f, -.7f, -.7f );
562  glEnd();
563 
564  // left
565  glColor3f( 0.5f, 1.0f, 1.0f );
566  glNormal3f( 1.f, 0.f, 0.f );
567  glBegin( GL_TRIANGLE_STRIP );
568  glVertex3f( -1.0f, .7f, .7f );
569  glVertex3f( -1.0f, -.7f, .7f );
570  glVertex3f( -1.0f, .7f, -.7f );
571  glVertex3f( -1.0f, -.7f, -.7f );
572  glEnd();
573 
574  EQ_GL_CALL( glPopAttrib( ));
575 }
576 
577 
578 }
EQ_API bool writeImages(const std::string &filenameTemplate) const
Write all valid pixel data as separate images.
uint32_t buffers
The Frame buffer attachments to use.
Definition: compositor.h:53
const PixelViewport & getPixelViewport() const
Zoom zoom
The zoom factor.
Definition: compositor.h:57
A channel represents a two-dimensional viewport within a Window.
Vector2i offset
The offset wrt destination window.
Definition: compositor.h:54
virtual void frameDraw(const eq::uint128_t &frameID)
Draw the scene.
static uint32_t assembleFramesCPU(const Frames &frames, Channel *channel, const bool blendAlpha=false)
Assemble all frames in the given order in a memory buffer using the CPU before assembling the result ...
virtual EQ_API void frameStart(const uint128_t &frameID, const uint32_t frameNumber)
Start rendering a frame.
EQ_API bool startReadback(const uint32_t buffers, const PixelViewport &pvp, const Zoom &zoom, util::ObjectManager &glObjects)
Start reading back an image from the frame buffer.
virtual EQ_API void frameDraw(const uint128_t &frameID)
Draw the scene.
static void assembleImageDB_FF(const Image *image, const ImageOp &op)
Start a Z-based assembly of the image color and depth attachment, based on OpenGL 1...
EQ_API void flush()
Free all cached data of this image.
The pixel data structure manages the pixel information for images.
Definition: pixelData.h:33
OpenGL Exception.
Definition: glException.h:27
EQ_API void bindFrameBuffer()
Rebind the current alternate FBO of the channel or window.
virtual EQ_API void applyViewport() const
Apply the OpenGL viewport for the current rendering task.
virtual EQ_API void applyFrustum() const
Apply the frustum matrix for the current rendering task.
static void assembleImage(const Image *image, const ImageOp &operation)
Assemble an image into the frame buffer.
EQ_API uint32_t getExternalFormat(const Frame::Buffer buffer) const
Get the external format of the given buffer.
virtual void frameStart(const eq::uint128_t &frameID, const uint32_t frameNumber)
Start rendering a frame.
EQ_API void sendEvent(ConfigEvent &event)
Send an (old) event to the application node.
virtual bool configExit()
Exit this channel.
A structure describing an image assembly task.
Definition: compositor.h:46
std::vector< Image * > Images
A vector of pointers to eq::Image.
EQ_API util::ObjectManager & getObjectManager()
EQFABRIC_API const std::string & getName() const
A Window represents an on-screen or off-screen drawable.
EQ_API Config * getConfig()
EQ_API const GLEWContext * glewGetContext() const
Get the GLEW context for this channel.
A holder for pixel data.
Definition: image.h:35
EQ_API bool hasPixelData(const Frame::Buffer buffer) const
virtual EQ_API void applyHeadTransform() const
Apply the transformation to position the view frustum.
EQ_API void setInternalFormat(const Frame::Buffer buffer, const uint32_t internalFormat)
Set the internal format for the given buffer.
A holder for multiple images.
static void assembleImageDB_GLSL(const Image *image, const ImageOp &op)
Start a Z-based assembly of the image color and depth attachment, using GLSL.
virtual EQ_API bool configExit()
Exit this channel.
const lunchbox::Clock * getClock() const
use main memory to store pixel data
Definition: fabric/frame.h:52
EQ_API const Images & getImages() const
EQ_API uint32_t getPixelDataSize(const Frame::Buffer buffer) const
A facility class to manage OpenGL objects across shared contexts.
Definition: objectManager.h:51
EQ_API void clearPixelData(const Frame::Buffer buffer)
Clear and validate an image buffer.
virtual EQ_API void setupAssemblyState()
Setup the OpenGL state for a readback or assemble operation.
EQ_API Image * newImage(const Frame::Type type, const DrawableConfig &config)
Allocate and add a new image.
EQ_API void setQuality(const Frame::Buffer buffer, const float quality)
Set the minimum quality after a full download-compression path.
virtual EQ_API void applyBuffer()
Apply the current rendering buffer, including the color mask.
lunchbox::RefPtr< FrameData > FrameDataPtr
A reference-counted pointer to an eq::FrameData.
virtual EQ_API void resetAssemblyState()
Reset the OpenGL state after an assembly operation.
EQ_API void setPixelViewport(const PixelViewport &pvp)
Set the internal pixel viewport of the image.
Channel * channel
The destination channel.
Definition: compositor.h:52
PixelViewport pvp
The dimensions of the pixel data in pixels.
Definition: pixelData.h:82
EQ_API const PixelData & getPixelData(const Frame::Buffer) const
EQ_API FrameDataPtr getFrameData()
Exception class for Equalizer operations.
Definition: exception.h:26
EQ_API void setAlphaUsage(const bool enabled)
Set alpha data preservation during download and compression.