2
0
forked from Ivasoft/DSView

LogicSnapshot class make mipmap by real-time

This commit is contained in:
dreamsourcelabTAI
2022-12-15 16:15:37 +08:00
parent 307c56dd62
commit 747c750d19
2 changed files with 108 additions and 68 deletions

View File

@@ -86,7 +86,7 @@ void LogicSnapshot::init()
void LogicSnapshot::init_all()
{
_sample_count = 0;
_sample_count = 0;
_ring_sample_count = 0;
_block_num = 0;
_byte_fraction = 0;
@@ -139,7 +139,7 @@ void LogicSnapshot::first_payload(const sr_datafeed_logic &logic, uint64_t total
for (uint64_t j = 0; j < rootnode_size; j++) {
struct RootNode rn;
rn.tog = 0;
rn.value = 0;
rn.value = 0;
memset(rn.lbp, 0, sizeof(rn.lbp));
root_vector.push_back(rn);
}
@@ -153,6 +153,11 @@ void LogicSnapshot::first_payload(const sr_datafeed_logic &logic, uint64_t total
for(auto& iter_rn : iter) {
iter_rn.tog = 0;
iter_rn.value = 0;
for (int j=0; j<64; j++){
if (iter_rn.lbp[j] != NULL)
memset(iter_rn.lbp[j], 0, LeafBlockSpace);
}
}
}
}
@@ -160,9 +165,11 @@ void LogicSnapshot::first_payload(const sr_datafeed_logic &logic, uint64_t total
assert(_channel_num < CHANNEL_MAX_COUNT);
_sample_count = 0;
_ring_sample_count = 0;
for (unsigned int i = 0; i < _channel_num; i++) {
_last_sample[i] = 0;
_last_calc_count[i] = 0;
}
append_payload(logic);
@@ -197,12 +204,10 @@ void LogicSnapshot::append_cross_payload(const sr_datafeed_logic &logic)
// _sample_count should be fixed in the last packet
// so _total_sample_count must be align to LeafBlock
uint64_t samples = ceil(logic.length * 8.0 / _channel_num);
if (_sample_count + samples < _total_sample_count) {
if (_sample_count + samples < _total_sample_count)
_sample_count += samples;
}
else {
else
_sample_count = _total_sample_count;
}
// malloc block buffer
while (_sample_count > _block_num * LeafBlockSamples) {
@@ -211,16 +216,16 @@ void LogicSnapshot::append_cross_payload(const sr_datafeed_logic &logic)
for(auto& iter : _ch_data) {
if (iter[index0].lbp[index1] == NULL){
iter[index0].lbp[index1] = malloc(LeafBlockSpace);
void *lbp = malloc(LeafBlockSpace);
if (iter[index0].lbp[index1] == NULL) {
if (lbp == NULL) {
_memory_failed = true;
return;
}
}
iter[index0].lbp[index1] = lbp;
}
uint8_t *mipmap_ptr = (uint8_t*)iter[index0].lbp[index1] + (LeafBlockSamples / 8);
memset(mipmap_ptr, 0, LeafBlockSpace - (LeafBlockSamples / 8));
memset(iter[index0].lbp[index1], 0, LeafBlockSpace);
}
_block_num++;
}
@@ -250,8 +255,9 @@ void LogicSnapshot::append_cross_payload(const sr_datafeed_logic &logic)
if (_ch_fraction == 0){
_ring_sample_count += Scale;
if (_ring_sample_count % LeafBlockSamples == 0)
calc_mipmap(_channel_num - 1, index0, index1, LeafBlockSamples);
if (_ring_sample_count % LeafBlockSamples == 0){
calc_mipmap(_channel_num - 1, index0, index1, LeafBlockSamples, true);
}
break;
}
@@ -290,7 +296,7 @@ void LogicSnapshot::append_cross_payload(const sr_datafeed_logic &logic)
if (align_space == LeafBlockSamples)
{
calc_mipmap(_ch_fraction, index0, index1, LeafBlockSamples);
calc_mipmap(_ch_fraction, index0, index1, LeafBlockSamples, true);
chans_read_addr[_ch_fraction] = read_ptr;
_ch_fraction = (_ch_fraction + 1) % _channel_num;
@@ -309,9 +315,11 @@ void LogicSnapshot::append_cross_payload(const sr_datafeed_logic &logic)
}
else if (read_ptr >= end_read_ptr)
{
calc_mipmap(_ch_fraction, index0, index1, align_space, false);
_ch_fraction = (_ch_fraction + 1) % _channel_num;
if (_ch_fraction == 0)
if (_ch_fraction == 0)
align_sample_count += (align_space - old_align_space);
index0 = align_sample_count / LeafBlockSamples / RootScale;
@@ -341,7 +349,35 @@ void LogicSnapshot::append_cross_payload(const sr_datafeed_logic &logic)
}
}
void LogicSnapshot::calc_mipmap(unsigned int order, uint8_t index0, uint8_t index1, uint64_t samples)
void LogicSnapshot::capture_ended()
{
std::lock_guard<std::mutex> lock(_mutex);
Snapshot::capture_ended();
uint64_t index0 = _ring_sample_count / LeafBlockSamples / RootScale;
uint64_t index1 = (_ring_sample_count / LeafBlockSamples) % RootScale;
uint64_t offset = (_ring_sample_count % LeafBlockSamples) / 8;
_sample_count = _ring_sample_count;
if (offset == 0)
return;
for (int chan=0; chan<_channel_num; chan++)
{
const uint64_t *end_ptr = (uint64_t*)_ch_data[chan][index0].lbp[index1] + (LeafBlockSamples / Scale);
uint64_t *ptr = (uint64_t*)((uint8_t*)_ch_data[chan][index0].lbp[index1] + offset);
while (ptr < end_ptr){
*ptr++ = 0;
}
calc_mipmap(chan, index0, index1, offset * 8, true);
}
}
void LogicSnapshot::calc_mipmap(unsigned int order, uint8_t index0, uint8_t index1, uint64_t samples, bool isEnd)
{
const uint64_t mask = 1ULL << (Scale - 1);
void *lbp = _ch_data[order][index0].lbp[index1];
@@ -353,11 +389,20 @@ void LogicSnapshot::calc_mipmap(unsigned int order, uint8_t index0, uint8_t inde
uint64_t *src_ptr = (uint64_t*)lbp;
uint64_t *dest_ptr = (uint64_t*)level1_ptr;
uint8_t offset = 0;
uint64_t i = 0;
uint64_t last_count = _last_calc_count[order];
for(unsigned int i = 0; i < samples / Scale; i++)
if (last_count > 0){
i = last_count / Scale;
offset = i % Scale;
src_ptr += i;
dest_ptr += i / Scale;
}
for(; i < samples / Scale; i++)
{
if (_last_sample[order] ^ *src_ptr)
*dest_ptr += (1ULL << offset);
*dest_ptr |= (1ULL << offset);
_last_sample[order] = *src_ptr & mask ? ~0ULL : 0ULL;
src_ptr++;
@@ -373,11 +418,19 @@ void LogicSnapshot::calc_mipmap(unsigned int order, uint8_t index0, uint8_t inde
src_ptr = (uint64_t*)level1_ptr;
dest_ptr = (uint64_t*)level2_ptr;
offset = 0;
i = 0;
for(unsigned int i = 0; i < LeafBlockSamples / Scale / Scale; i++)
if (last_count > 0){
i = last_count / Scale / Scale;
offset = i % Scale;
src_ptr += i;
dest_ptr += i / Scale;
}
for(; i < LeafBlockSamples / Scale / Scale; i++)
{
if (*src_ptr)
*dest_ptr += (1ULL << offset);
*dest_ptr |= (1ULL << offset);
src_ptr++;
offset++;
@@ -392,54 +445,33 @@ void LogicSnapshot::calc_mipmap(unsigned int order, uint8_t index0, uint8_t inde
src_ptr = (uint64_t*)level2_ptr;
dest_ptr = (uint64_t*)level3_ptr;
for (unsigned int i=0; i < Scale; i++)
for (i=0; i < Scale; i++)
{
if (*src_ptr)
*dest_ptr += (1ULL << i);
*dest_ptr |= (1ULL << i);
src_ptr++;
}
if (*((uint64_t*)lbp) != 0)
_ch_data[order][index0].value += 1ULL<< index1;
_ch_data[order][index0].value |= 1ULL << index1;
if (*((uint64_t*)level3_ptr) != 0){
_ch_data[order][index0].tog += 1ULL << index1;
_ch_data[order][index0].tog |= 1ULL << index1;
}
else{
else if (isEnd){
free(_ch_data[order][index0].lbp[index1]);
_ch_data[order][index0].lbp[index1] = NULL;
}
if (isEnd)
_last_calc_count[order] = 0;
else
_last_calc_count[order] = samples;
}
void LogicSnapshot::capture_ended()
{
Snapshot::capture_ended();
uint64_t index0 = _ring_sample_count / LeafBlockSamples / RootScale;
uint64_t index1 = (_ring_sample_count / LeafBlockSamples) % RootScale;
uint64_t offset = (_ring_sample_count % LeafBlockSamples) / 8;
_sample_count = _ring_sample_count;
if (offset == 0)
return;
for (int i=0; i<_channel_num; i++)
{
const uint64_t *end_ptr = (uint64_t*)_ch_data[i][index0].lbp[index1] + (LeafBlockSamples / Scale);
uint64_t *ptr = (uint64_t*)((uint8_t*)_ch_data[i][index0].lbp[index1] + offset);
while (ptr < end_ptr){
*ptr++ = 0;
}
calc_mipmap(i, index0, index1, offset * 8);
}
}
const uint8_t *LogicSnapshot::get_samples(uint64_t start_sample, uint64_t &end_sample, int sig_index)
{
uint64_t sample_count = get_sample_count();
uint64_t sample_count = _sample_count;
assert(start_sample < sample_count);
assert(end_sample <= sample_count);
assert(start_sample <= end_sample);
@@ -467,17 +499,13 @@ bool LogicSnapshot::get_sample(uint64_t index, int sig_index)
assert(order != -1);
assert(_ch_data[order].size() != 0);
if (index < get_sample_count()) {
if (index < _ring_sample_count) {
uint64_t index_mask = 1ULL << (index & LevelMask[0]);
uint64_t index0 = index >> (LeafBlockPower + RootScalePower);
uint64_t index1 = (index & RootMask) >> LeafBlockPower;
uint64_t root_pos_mask = 1ULL << index1;
uint64_t index0_r = _ring_sample_count >> (LeafBlockPower + RootScalePower);
uint64_t index1_r = (_ring_sample_count >> LeafBlockPower) % RootScale;
bool bAble = index0 < index0_r || (index0 == index0_r && index1 <= index1_r);
if (bAble && (_ch_data[order][index0].tog & root_pos_mask) == 0) {
if ((_ch_data[order][index0].tog & root_pos_mask) == 0) {
return (_ch_data[order][index0].value & root_pos_mask) != 0;
}
else {
@@ -499,10 +527,12 @@ bool LogicSnapshot::get_display_edges(std::vector<std::pair<bool, bool> > &edges
if (!togs.empty())
togs.clear();
if (get_sample_count() == 0)
std::lock_guard<std::mutex> lock(_mutex);
if (_ring_sample_count == 0)
return false;
assert(end < get_sample_count());
assert(end < _ring_sample_count);
assert(start <= end);
assert(min_length > 0);
@@ -513,6 +543,7 @@ bool LogicSnapshot::get_display_edges(std::vector<std::pair<bool, bool> > &edges
// Get the initial state
start_sample = last_sample = get_sample(index++, sig_index);
togs.push_back(pair<uint16_t, bool>(0, last_sample));
while(edges.size() < width) {
// search next edge
bool has_edge = get_nxt_edge(index, last_sample, end, 0, sig_index);
@@ -520,8 +551,10 @@ bool LogicSnapshot::get_display_edges(std::vector<std::pair<bool, bool> > &edges
// calc the edge position
int64_t gap = (index / min_length) - pixels_offset;
index = max((uint64_t)ceil((floor(index/min_length) + 1) * min_length), index + 1);
while(gap > (int64_t)edges.size() && edges.size() < width)
while(gap > (int64_t)edges.size() && edges.size() < width){
edges.push_back(pair<bool, bool>(false, last_sample));
}
if (index > end)
last_sample = get_sample(end, sig_index);
@@ -567,11 +600,17 @@ bool LogicSnapshot::get_nxt_edge(uint64_t &index, bool last_sample, uint64_t end
uint64_t cur_mask = (~0ULL << root_pos);
do {
uint64_t cur_tog = _ch_data[order][i].tog & cur_mask;
uint64_t cur_tog = _ch_data[order][i].tog & cur_mask;
if (cur_tog != 0) {
uint64_t first_edge_pos = bsf_folded(cur_tog);
uint64_t first_edge_pos = bsf_folded(cur_tog);
uint64_t *lbp = (uint64_t*)_ch_data[order][i].lbp[first_edge_pos];
if (lbp == NULL){
dsv_info("lbp is null.");
assert(false);
}
uint64_t blk_start = (i << (LeafBlockPower + RootScalePower)) + (first_edge_pos << LeafBlockPower);
index = max(blk_start, index);
@@ -603,7 +642,7 @@ bool LogicSnapshot::get_nxt_edge(uint64_t &index, bool last_sample, uint64_t end
bool LogicSnapshot::get_pre_edge(uint64_t &index, bool last_sample,
double min_length, int sig_index)
{
assert(index < get_sample_count());
assert(index < _ring_sample_count);
int order = get_ch_order(sig_index);
if (order == -1)

View File

@@ -31,7 +31,7 @@
#include <vector>
#include <map>
#define CHANNEL_MAX_COUNT 512
#define CHANNEL_MAX_COUNT 512
namespace LogicSnapshotTest {
class Pow2;
@@ -69,7 +69,7 @@ private:
struct RootNode
{
uint64_t tog;
uint64_t value;
uint64_t value;
void *lbp[Scale];
};
@@ -122,7 +122,7 @@ public:
private:
int get_ch_order(int sig_index);
void calc_mipmap(unsigned int order, uint8_t index0, uint8_t index1, uint64_t samples);
void calc_mipmap(unsigned int order, uint8_t index0, uint8_t index1, uint64_t samples, bool isEnd);
void append_cross_payload(const sr_datafeed_logic &logic);
@@ -191,6 +191,7 @@ private:
uint8_t *_dest_ptr;
uint64_t _last_sample[CHANNEL_MAX_COUNT];
uint64_t _last_calc_count[CHANNEL_MAX_COUNT];
friend class LogicSnapshotTest::Pow2;
friend class LogicSnapshotTest::Basic;