Skip to content

Commit

Permalink
Initial api to provide stateless read api for scanline things
Browse files Browse the repository at this point in the history
This enables reading of scanlines in a "stateless" manner, where a
framebuffer does not have to be stored, then the call to readPixels
made.

Signed-off-by: Kimball Thurston <[email protected]>
  • Loading branch information
kdt3rd committed Sep 23, 2024
1 parent 6245d6e commit c7d03a8
Show file tree
Hide file tree
Showing 7 changed files with 91 additions and 1 deletion.
40 changes: 40 additions & 0 deletions src/lib/OpenEXR/ImfInputFile.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -77,10 +77,14 @@ struct InputFile::Data
}

void setFrameBuffer (const FrameBuffer& frameBuffer);
void lockedSetFrameBuffer (const FrameBuffer& frameBuffer);

void readPixels (int scanline1, int scanline2);
void bufferedReadPixels (int scanline1, int scanline2);

void readPixels (
const FrameBuffer& frameBuffer, int scanline1, int scanline2);

void deleteCachedBuffer (void);
void copyCachedBuffer (FrameBuffer::ConstIterator to,
FrameBuffer::ConstIterator from,
Expand Down Expand Up @@ -224,6 +228,13 @@ InputFile::readPixels (int scanLine)
_data->readPixels (scanLine, scanLine);
}

void
InputFile::readPixels (
const FrameBuffer& frameBuffer, int scanLine1, int scanLine2)
{
_data->readPixels (frameBuffer, scanLine1, scanLine2);
}

void
InputFile::rawPixelData (
int firstScanLine, const char*& pixelData, int& pixelDataSize)
Expand Down Expand Up @@ -317,7 +328,12 @@ InputFile::Data::setFrameBuffer (const FrameBuffer& frameBuffer)
#if ILMTHREAD_THREADING_ENABLED
std::lock_guard<std::mutex> lk (_mx);
#endif
lockedSetFrameBuffer (frameBuffer);
}

void
InputFile::Data::lockedSetFrameBuffer (const FrameBuffer& frameBuffer)
{
if (_storage == EXR_STORAGE_TILED)
{
//
Expand Down Expand Up @@ -430,6 +446,30 @@ InputFile::Data::readPixels (int scanLine1, int scanLine2)
else { _sFile->readPixels (scanLine1, scanLine2); }
}

void
InputFile::Data::readPixels (
const FrameBuffer& frameBuffer, int scanLine1, int scanLine2)
{
if (_compositor)
{
#if ILMTHREAD_THREADING_ENABLED
std::lock_guard<std::mutex> lock (_mx);
#endif
_compositor->setFrameBuffer (frameBuffer);
_compositor->readPixels (scanLine1, scanLine2);
}
else if (_storage == EXR_STORAGE_TILED)
{
#if ILMTHREAD_THREADING_ENABLED
std::lock_guard<std::mutex> lock (_mx);
#endif

lockedSetFrameBuffer (frameBuffer);
bufferedReadPixels (scanLine1, scanLine2);
}
else { _sFile->readPixels (frameBuffer, scanLine1, scanLine2); }
}

void
InputFile::Data::bufferedReadPixels (int scanLine1, int scanLine2)
{
Expand Down
21 changes: 21 additions & 0 deletions src/lib/OpenEXR/ImfInputFile.h
Original file line number Diff line number Diff line change
Expand Up @@ -200,6 +200,27 @@ class IMF_EXPORT_TYPE InputFile
IMF_EXPORT
void readPixels (int scanLine);

//----------------------------------------------
// Combines the setFrameBuffer and readPixels into a singular
// call. This does more than that in that it can, with the right
// conditions, not require a lock on the file, such that multiple
// (external to OpenEXR) threads can read at the same time on
// different framebuffers
//
// NB: if the underlying file is deep or tiled, that requires
// translation, so will not do the pass through, but will behave
// in a threadsafe manner (where the only way that was possible
// before was to have a larger framebuffer, set the framebuffer
// once, then call readPixels by the external threads, although
// that occured with a mutex and so the reads were serialized.
// There are reasons why that might still be serialized, such as a
// non-threadable stream.
//----------------------------------------------

IMF_EXPORT
void readPixels (
const FrameBuffer& frameBuffer, int scanLine1, int scanLine2);

//----------------------------------------------
// Read a block of raw pixel data from the file,
// without uncompressing it (this function is
Expand Down
7 changes: 7 additions & 0 deletions src/lib/OpenEXR/ImfInputPart.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,13 @@ InputPart::readPixels (int scanLine)
file->readPixels (scanLine);
}

void
InputPart::readPixels (
const FrameBuffer& frameBuffer, int scanLine1, int scanLine2)
{
file->readPixels (frameBuffer, scanLine1, scanLine2);
}

void
InputPart::rawPixelData (
int firstScanLine, const char*& pixelData, int& pixelDataSize)
Expand Down
3 changes: 3 additions & 0 deletions src/lib/OpenEXR/ImfInputPart.h
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,9 @@ class IMF_EXPORT_TYPE InputPart
IMF_EXPORT
void readPixels (int scanLine);
IMF_EXPORT
void readPixels (
const FrameBuffer& frameBuffer, int scanLine1, int scanLine2);
IMF_EXPORT
void rawPixelData (
int firstScanLine, const char*& pixelData, int& pixelDataSize);

Expand Down
2 changes: 1 addition & 1 deletion src/lib/OpenEXR/ImfMultiPartInputFile.h
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,7 @@ class IMF_EXPORT_TYPE MultiPartInputFile
//
// used internally by 'Part' types to access individual parts of the multipart file
//
// TODO: change these to value / reference semantics
// TODO: change these to value / reference semantics (smart ptr)
template <class T> IMF_HIDDEN T* getInputPart (int partNumber);
IMF_HIDDEN InputPartData* getPart (int) const;

Expand Down
7 changes: 7 additions & 0 deletions src/lib/OpenEXR/ImfScanLineInputFile.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -285,6 +285,13 @@ ScanLineInputFile::readPixels (int scanLine1, int scanLine2)
_data->readPixels (frameBuffer (), scanLine1, scanLine2);
}

void
ScanLineInputFile::readPixels (
const FrameBuffer& frame, int scanLine1, int scanLine2)
{
_data->readPixels (frame, scanLine1, scanLine2);
}

////////////////////////////////////////

void
Expand Down
12 changes: 12 additions & 0 deletions src/lib/OpenEXR/ImfScanLineInputFile.h
Original file line number Diff line number Diff line change
Expand Up @@ -140,6 +140,18 @@ class IMF_EXPORT_TYPE ScanLineInputFile
IMF_EXPORT
void readPixels (int scanLine);

//----------------------------------------------
// Combines the setFrameBuffer and readPixels into a singular
// call. This does more than that in that it can, with the right
// conditions, not require a lock on the file, such that multiple
// (external to OpenEXR) threads can read at the same time on
// different framebuffers
//----------------------------------------------

IMF_EXPORT
void readPixels (
const FrameBuffer& frame, int scanLine1, int scanLine2);

//----------------------------------------------
// Read a block of raw pixel data from the file,
// without uncompressing it (this function is
Expand Down

0 comments on commit c7d03a8

Please sign in to comment.