2011-09-18 15:28:58 +02:00
|
|
|
|
/*
|
|
|
|
|
|
TESTFRAME.hpp - test data frame (stub) for checking Render engine functionality
|
|
|
|
|
|
|
Copyright: clarify and simplify the file headers
* Lumiera source code always was copyrighted by individual contributors
* there is no entity "Lumiera.org" which holds any copyrights
* Lumiera source code is provided under the GPL Version 2+
== Explanations ==
Lumiera as a whole is distributed under Copyleft, GNU General Public License Version 2 or above.
For this to become legally effective, the ''File COPYING in the root directory is sufficient.''
The licensing header in each file is not strictly necessary, yet considered good practice;
attaching a licence notice increases the likeliness that this information is retained
in case someone extracts individual code files. However, it is not by the presence of some
text, that legally binding licensing terms become effective; rather the fact matters that a
given piece of code was provably copyrighted and published under a license. Even reformatting
the code, renaming some variables or deleting parts of the code will not alter this legal
situation, but rather creates a derivative work, which is likewise covered by the GPL!
The most relevant information in the file header is the notice regarding the
time of the first individual copyright claim. By virtue of this initial copyright,
the first author is entitled to choose the terms of licensing. All further
modifications are permitted and covered by the License. The specific wording
or format of the copyright header is not legally relevant, as long as the
intention to publish under the GPL remains clear. The extended wording was
based on a recommendation by the FSF. It can be shortened, because the full terms
of the license are provided alongside the distribution, in the file COPYING.
2024-11-17 23:42:55 +01:00
|
|
|
|
Copyright (C)
|
2024-11-20 15:32:49 +01:00
|
|
|
|
2011, 2024 Hermann Vosseler <Ichthyostega@web.de>
|
Copyright: clarify and simplify the file headers
* Lumiera source code always was copyrighted by individual contributors
* there is no entity "Lumiera.org" which holds any copyrights
* Lumiera source code is provided under the GPL Version 2+
== Explanations ==
Lumiera as a whole is distributed under Copyleft, GNU General Public License Version 2 or above.
For this to become legally effective, the ''File COPYING in the root directory is sufficient.''
The licensing header in each file is not strictly necessary, yet considered good practice;
attaching a licence notice increases the likeliness that this information is retained
in case someone extracts individual code files. However, it is not by the presence of some
text, that legally binding licensing terms become effective; rather the fact matters that a
given piece of code was provably copyrighted and published under a license. Even reformatting
the code, renaming some variables or deleting parts of the code will not alter this legal
situation, but rather creates a derivative work, which is likewise covered by the GPL!
The most relevant information in the file header is the notice regarding the
time of the first individual copyright claim. By virtue of this initial copyright,
the first author is entitled to choose the terms of licensing. All further
modifications are permitted and covered by the License. The specific wording
or format of the copyright header is not legally relevant, as long as the
intention to publish under the GPL remains clear. The extended wording was
based on a recommendation by the FSF. It can be shortened, because the full terms
of the license are provided alongside the distribution, in the file COPYING.
2024-11-17 23:42:55 +01:00
|
|
|
|
|
|
|
|
|
|
**Lumiera** is free software; you can redistribute it and/or modify it
|
|
|
|
|
|
under the terms of the GNU General Public License as published by the
|
|
|
|
|
|
Free Software Foundation; either version 2 of the License, or (at your
|
|
|
|
|
|
option) any later version. See the file COPYING for further details.
|
2011-09-18 15:28:58 +02:00
|
|
|
|
|
|
|
|
|
|
*/
|
|
|
|
|
|
|
2017-02-22 01:58:49 +01:00
|
|
|
|
/** @file testframe.hpp
|
2024-11-20 05:50:44 +01:00
|
|
|
|
** Unit test helper to generate fake test data frames.
|
|
|
|
|
|
** Each TestFrame holds a 1k buffer of byte data, which can be
|
|
|
|
|
|
** verified, accessed and manipulated to emulate media computations.
|
|
|
|
|
|
** A [metadata header](\ref steam::engine::test::TestFrame::Meta) is placed
|
|
|
|
|
|
** in memory behind the working buffer, which allows to detect data corruption
|
|
|
|
|
|
** and stores a lifecycle phase and a data checksum.
|
|
|
|
|
|
**
|
|
|
|
|
|
** The contents of each TestFrame are filled on creation with pseudo-random data,
|
2024-11-20 15:32:49 +01:00
|
|
|
|
** which is created from a _discriminator seed,_ based on a »family« and a »frameNr«
|
|
|
|
|
|
** within each family(≙channel). Due to the deterministic nature of these computations,
|
|
|
|
|
|
** the _pristine state_ of any frame can be determined. But the payload data is accessible
|
2024-11-20 05:50:44 +01:00
|
|
|
|
** and can be manipulated, and a new [checksum can be recorded](\ref TestFrame::markChecksum).
|
|
|
|
|
|
**
|
2024-11-20 15:32:49 +01:00
|
|
|
|
** For ease of testing, a static [store of TestFrame instances](\ref #testData) is built and
|
|
|
|
|
|
** retained in heap memory, and an arbitrary memory location can be treated as TestFrame.
|
2016-11-03 18:20:10 +01:00
|
|
|
|
*/
|
|
|
|
|
|
|
2011-09-18 15:28:58 +02:00
|
|
|
|
|
2018-11-15 23:52:02 +01:00
|
|
|
|
#ifndef STEAM_ENGINE_TESTFRAME_H
|
|
|
|
|
|
#define STEAM_ENGINE_TESTFRAME_H
|
2011-09-18 15:28:58 +02:00
|
|
|
|
|
|
|
|
|
|
|
2024-11-05 21:23:13 +01:00
|
|
|
|
#include "lib/integral.hpp"
|
2024-11-18 02:45:37 +01:00
|
|
|
|
#include "lib/hash-value.h"
|
2024-11-05 21:23:13 +01:00
|
|
|
|
|
|
|
|
|
|
#include <array>
|
2011-09-18 15:28:58 +02:00
|
|
|
|
|
|
|
|
|
|
|
2018-11-15 23:55:13 +01:00
|
|
|
|
namespace steam {
|
2011-09-18 15:28:58 +02:00
|
|
|
|
namespace engine {
|
|
|
|
|
|
namespace test {
|
|
|
|
|
|
|
2024-11-18 23:55:30 +01:00
|
|
|
|
using lib::HashVal;
|
2011-09-18 15:28:58 +02:00
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
* Mock data frame for simulated rendering.
|
|
|
|
|
|
* A test frame can be created and placed instead of a real data frame.
|
|
|
|
|
|
* It doesn't depend on any external libraries and will be self-maintaining.
|
|
|
|
|
|
* Placeholder functions are provided for assignment (simulating the actual
|
|
|
|
|
|
* calculations); additional diagnostic functions allow to verify the
|
|
|
|
|
|
* performed operations after-the fact
|
2011-10-31 02:20:32 +01:00
|
|
|
|
*
|
|
|
|
|
|
* Each TestFrame is automatically filled with pseudo random data;
|
|
|
|
|
|
* multiple frames are arranged in sequences and channels, causing the random data
|
2011-11-01 03:11:43 +01:00
|
|
|
|
* to be reproducible yet different within each frame. TestFrame's lifecycle is
|
|
|
|
|
|
* tracked and marked in an embedded state field. Moreover, the contents of the
|
|
|
|
|
|
* data block can be verified, because the sequence of bytes is reproducible,
|
2011-10-31 02:20:32 +01:00
|
|
|
|
* based on the channel and sequence number of the test frame.
|
|
|
|
|
|
*
|
2011-11-01 03:11:43 +01:00
|
|
|
|
* @see TestFrame_test
|
|
|
|
|
|
* @see OutputSlotProtocol_test
|
2011-09-18 15:28:58 +02:00
|
|
|
|
*
|
|
|
|
|
|
*/
|
|
|
|
|
|
class TestFrame
|
|
|
|
|
|
{
|
2011-10-31 00:13:35 +01:00
|
|
|
|
enum StageOfLife {
|
|
|
|
|
|
CREATED, EMITTED, DISCARDED
|
|
|
|
|
|
};
|
|
|
|
|
|
|
2024-11-05 21:23:13 +01:00
|
|
|
|
static constexpr size_t BUFFSIZ = 1024;
|
|
|
|
|
|
using _Arr = std::array<char,BUFFSIZ>;
|
2024-11-20 21:44:50 +01:00
|
|
|
|
using _A64 = std::array<uint64_t, BUFFSIZ/sizeof(uint64_t)>;
|
2024-11-18 23:55:30 +01:00
|
|
|
|
|
|
|
|
|
|
struct Meta
|
|
|
|
|
|
{
|
|
|
|
|
|
HashVal _MARK_;
|
|
|
|
|
|
HashVal checksum;
|
|
|
|
|
|
uint64_t distinction;
|
|
|
|
|
|
StageOfLife stage;
|
|
|
|
|
|
|
|
|
|
|
|
Meta (uint seq, uint family);
|
2024-11-20 05:50:44 +01:00
|
|
|
|
bool isPlausible() const;
|
|
|
|
|
|
bool operator== (Meta const&) const;
|
2024-11-18 23:55:30 +01:00
|
|
|
|
};
|
2011-10-31 00:13:35 +01:00
|
|
|
|
|
2024-11-05 21:23:13 +01:00
|
|
|
|
/** inline storage buffer for the payload media data */
|
|
|
|
|
|
alignas(uint64_t)
|
|
|
|
|
|
std::byte buffer_[sizeof(_Arr)];
|
2011-09-18 15:28:58 +02:00
|
|
|
|
|
2024-11-18 23:55:30 +01:00
|
|
|
|
/** Metadata record located behind the data buffer */
|
|
|
|
|
|
Meta header_;
|
|
|
|
|
|
|
2011-09-18 15:28:58 +02:00
|
|
|
|
public:
|
2024-11-18 02:45:37 +01:00
|
|
|
|
/** discard all cached #testData and recalibrate data generation */
|
|
|
|
|
|
static void reseed();
|
|
|
|
|
|
|
2011-10-31 00:13:35 +01:00
|
|
|
|
~TestFrame();
|
|
|
|
|
|
TestFrame (uint seq=0, uint family=0);
|
|
|
|
|
|
TestFrame (TestFrame const&);
|
|
|
|
|
|
TestFrame& operator= (TestFrame const&);
|
2011-09-19 01:42:37 +02:00
|
|
|
|
|
2024-11-20 05:50:44 +01:00
|
|
|
|
/** recompute and store checksum based on current contents */
|
|
|
|
|
|
HashVal markChecksum();
|
2025-02-10 22:48:31 +01:00
|
|
|
|
HashVal getChecksum();
|
2024-11-20 05:50:44 +01:00
|
|
|
|
|
2011-11-01 03:11:43 +01:00
|
|
|
|
/** Helper to verify that a given memory location holds
|
2011-10-30 05:35:36 +01:00
|
|
|
|
* an active TestFrame instance (created, not yet destroyed)
|
|
|
|
|
|
* @return true if the TestFrame datastructure is intact and
|
|
|
|
|
|
* marked as still alive.
|
|
|
|
|
|
*/
|
2011-10-31 00:13:35 +01:00
|
|
|
|
static bool isAlive (void* memLocation);
|
2011-10-30 05:35:36 +01:00
|
|
|
|
|
|
|
|
|
|
/** Helper to verify a given memory location holds
|
|
|
|
|
|
* an already destroyed TestFrame instance */
|
2011-10-31 00:13:35 +01:00
|
|
|
|
static bool isDead (void* memLocation);
|
|
|
|
|
|
|
2024-11-18 23:55:30 +01:00
|
|
|
|
bool isAlive() const;
|
|
|
|
|
|
bool isDead() const;
|
|
|
|
|
|
bool isSane() const;
|
|
|
|
|
|
bool isValid() const;
|
|
|
|
|
|
bool isPristine() const;
|
2011-10-30 05:35:36 +01:00
|
|
|
|
|
2011-10-31 00:13:35 +01:00
|
|
|
|
bool operator== (void* memLocation) const;
|
2011-09-19 01:42:37 +02:00
|
|
|
|
|
2011-10-31 00:13:35 +01:00
|
|
|
|
friend bool operator== (TestFrame const& f1, TestFrame const& f2) { return f1.contentEquals(f2); }
|
|
|
|
|
|
friend bool operator!= (TestFrame const& f1, TestFrame const& f2) { return !f1.contentEquals(f2); }
|
2024-11-05 21:23:13 +01:00
|
|
|
|
|
|
|
|
|
|
/** Array-style direct access to the payload data */
|
2024-11-20 21:44:50 +01:00
|
|
|
|
_Arr& data() { return * std::launder (reinterpret_cast<_Arr* > (&buffer_)); }
|
|
|
|
|
|
_Arr const& data() const { return * std::launder (reinterpret_cast<_Arr const*> (&buffer_)); }
|
|
|
|
|
|
_A64& data64() { return * std::launder (reinterpret_cast<_A64* > (&buffer_)); }
|
|
|
|
|
|
_A64 const& data64() const { return * std::launder (reinterpret_cast<_A64 const*> (&buffer_)); }
|
2011-09-19 01:42:37 +02:00
|
|
|
|
|
2011-10-31 00:13:35 +01:00
|
|
|
|
private:
|
2024-11-20 05:50:44 +01:00
|
|
|
|
void buildData();
|
2024-11-20 15:32:49 +01:00
|
|
|
|
Meta& accessHeader();
|
2024-11-18 23:55:30 +01:00
|
|
|
|
Meta const& accessHeader() const;
|
2024-11-20 15:32:49 +01:00
|
|
|
|
bool contentEquals (TestFrame const& o) const;
|
|
|
|
|
|
bool matchDistinction() const;
|
|
|
|
|
|
StageOfLife currStage() const;
|
|
|
|
|
|
HashVal computeChecksum() const;
|
|
|
|
|
|
bool hasValidChecksum() const;
|
2011-09-18 15:28:58 +02:00
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2011-10-31 02:20:32 +01:00
|
|
|
|
/** Helper to access a specific frame of test data at a fixed memory location.
|
|
|
|
|
|
* The series of test frames is generated on demand, but remains in memory thereafter,
|
|
|
|
|
|
* similar to real data accessible from some kind of source stream. Each of these generated
|
2024-11-20 15:32:49 +01:00
|
|
|
|
* test frames is filled with different yet reproducible pseudo random data.
|
2011-10-31 02:20:32 +01:00
|
|
|
|
* Client code is free to access and corrupt this data.
|
2024-11-20 15:32:49 +01:00
|
|
|
|
* @note TestFrame::reseed() discards this data and draws a new base seed from `defaultGen`
|
2011-10-31 02:20:32 +01:00
|
|
|
|
*/
|
2024-11-20 05:50:44 +01:00
|
|
|
|
TestFrame& testData (uint seqNr =0, uint chanNr =0);
|
2011-10-31 02:20:32 +01:00
|
|
|
|
|
|
|
|
|
|
|
2018-11-15 23:55:13 +01:00
|
|
|
|
}}} // namespace steam::engine::test
|
2011-09-18 15:28:58 +02:00
|
|
|
|
#endif
|