2
0
forked from Ivasoft/DSView

Merge branch 'dev-1.3' of https://github.com/dreamsourcelab/DSView into dev-1.3

This commit is contained in:
dreamsourcelabTAI
2023-06-13 11:47:18 +08:00
3 changed files with 235 additions and 60 deletions

View File

@@ -156,7 +156,8 @@ 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.first = 0;
rn.last = 0;
memset(rn.lbp, 0, sizeof(rn.lbp));
root_vector.push_back(rn);
}
@@ -170,7 +171,8 @@ void LogicSnapshot::first_payload(const sr_datafeed_logic &logic, uint64_t total
for(auto& iter : _ch_data) {
for(auto& iter_rn : iter) {
iter_rn.tog = 0;
iter_rn.value = 0;
iter_rn.first = 0;
iter_rn.last = 0;
for (int j=0; j<64; j++){
if (iter_rn.lbp[j] != NULL)
@@ -471,8 +473,7 @@ void LogicSnapshot::capture_ended()
}
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];
void *level1_ptr = (uint8_t*)lbp + LeafBlockSamples / 8;
void *level2_ptr = (uint8_t*)level1_ptr + LeafBlockSamples / Scale / 8;
@@ -492,12 +493,16 @@ void LogicSnapshot::calc_mipmap(unsigned int order, uint8_t index0, uint8_t inde
dest_ptr += i / Scale;
}
for(; i < samples / Scale; i++)
if (i == 0) {
_last_sample[order] = (*src_ptr & LSB) ? ~0ULL : 0ULL;
}
for(; i < samples / Scale; i++)
{
if (_last_sample[order] ^ *src_ptr)
*dest_ptr |= (1ULL << offset);
_last_sample[order] = *src_ptr & mask ? ~0ULL : 0ULL;
_last_sample[order] = *src_ptr & MSB ? ~0ULL : 0ULL;
src_ptr++;
offset++;
@@ -545,9 +550,12 @@ void LogicSnapshot::calc_mipmap(unsigned int order, uint8_t index0, uint8_t inde
src_ptr++;
}
if (*((uint64_t*)lbp) != 0)
_ch_data[order][index0].value |= 1ULL << index1;
if ((*((uint64_t*)lbp) & LSB) != 0)
_ch_data[order][index0].first |= 1ULL << index1;
if ((*((uint64_t*)lbp + LeafBlockSamples / Scale - 1) & MSB) != 0)
_ch_data[order][index0].last |= 1ULL << index1;
if (*((uint64_t*)level3_ptr) != 0){
_ch_data[order][index0].tog |= 1ULL << index1;
}
@@ -642,7 +650,7 @@ bool LogicSnapshot::get_sample_self(uint64_t index, int sig_index)
uint64_t root_pos_mask = 1ULL << index1;
if ((_ch_data[order][index0].tog & root_pos_mask) == 0) {
return (_ch_data[order][index0].value & root_pos_mask) != 0;
return (_ch_data[order][index0].first & root_pos_mask) != 0;
}
else {
uint64_t *lbp = (uint64_t*)_ch_data[order][index0].lbp[index1];
@@ -750,6 +758,8 @@ bool LogicSnapshot::get_nxt_edge_self(uint64_t &index, bool last_sample, uint64_
const unsigned int min_level = max((int)(log2f(min_length) - 1) / (int)ScalePower, 0);
uint64_t root_index = index >> (LeafBlockPower + RootScalePower);
uint8_t root_pos = (index & RootMask) >> LeafBlockPower;
bool root_last = (root_index != 0) ? _ch_data[order][root_index-1].last & MSB :
_ch_data[order][0].first & LSB;
bool edge_hit = false;
// linear search for the next transition on the root level
@@ -758,37 +768,59 @@ bool LogicSnapshot::get_nxt_edge_self(uint64_t &index, bool last_sample, uint64_
uint64_t cur_mask = (~0ULL << root_pos);
do {
uint64_t cur_tog = _ch_data[order][i].tog & cur_mask;
uint64_t inner_tog = _ch_data[order][i].tog & cur_mask;
uint64_t lbp_tog = (((_ch_data[order][i].last << 1) + root_last) & cur_mask) ^ (_ch_data[order][i].first & cur_mask);
uint8_t inner_tog_pos = bsf_folded(inner_tog);
uint8_t lbp_tog_pos = bsf_folded(lbp_tog);
if (cur_tog != 0) {
uint64_t first_edge_pos = bsf_folded(cur_tog);
uint64_t *lbp = (uint64_t*)_ch_data[order][i].lbp[first_edge_pos];
uint64_t blk_start = (i << (LeafBlockPower + RootScalePower)) + (first_edge_pos << LeafBlockPower);
index = max(blk_start, index);
if (min_level < ScaleLevel) {
uint64_t block_end = min(index | LeafMask, end);
edge_hit = block_nxt_edge(lbp, index, block_end, last_sample, min_level);
}
else {
edge_hit = true;
if (inner_tog != 0)
{
if (lbp_tog != 0) {
// lbp tog before inner tog
edge_hit = lbp_nxt_edge(index, i, lbp_tog, lbp_tog_pos, true, inner_tog_pos, last_sample, sig_index);
}
if (first_edge_pos == RootScale - 1)
break;
cur_mask = (~0ULL << (first_edge_pos + 1));
if (!edge_hit) {
uint64_t *lbp = (uint64_t*)_ch_data[order][i].lbp[inner_tog_pos];
uint64_t blk_start = (i << (LeafBlockPower + RootScalePower)) + (inner_tog_pos << LeafBlockPower);
index = max(blk_start, index);
if (min_level < ScaleLevel) {
uint64_t block_end = min(index | LeafMask, end);
edge_hit = block_nxt_edge(lbp, index, block_end, last_sample, min_level);
}
else {
edge_hit = true;
}
if (inner_tog_pos == RootScale - 1)
break;
cur_mask = (~0ULL << (inner_tog_pos + 1));
}
}
else if (lbp_tog != 0) {
// lbp tog
edge_hit = lbp_nxt_edge(index, i, lbp_tog, lbp_tog_pos, false, Scale - 1, last_sample, sig_index);
}
else {
index = (index + (1 << (LeafBlockPower + RootScalePower))) &
(~0ULL << (LeafBlockPower + RootScalePower));
//index = (index + (1 << (LeafBlockPower + RootScalePower))) &
// (~0ULL << (LeafBlockPower + RootScalePower));
index = (((i + 1) << (LeafBlockPower + RootScalePower)) - 1);
break;
}
}
while (!edge_hit && index < end);
//while (!edge_hit && index < end);
while (!edge_hit && index < (((i + 1) << (LeafBlockPower + RootScalePower)) - 1));
root_pos = 0;
root_last = _ch_data[order][i].last & MSB;
}
if (index > end) {
// skip edges over right
edge_hit = false;
}
return edge_hit;
}
@@ -802,7 +834,7 @@ bool LogicSnapshot::get_pre_edge(uint64_t &index, bool last_sample,
bool flag = get_pre_edge_self(index, last_sample, min_length, sig_index);
index -= _loop_offset;
index = (index < _loop_offset) ? 0 : index - _loop_offset;
_ring_sample_count -= _loop_offset;
return flag;
}
@@ -820,32 +852,108 @@ bool LogicSnapshot::get_pre_edge_self(uint64_t &index, bool last_sample,
const unsigned int min_level = max((int)(log2f(min_length) - 1) / (int)ScalePower, 0);
int root_index = index >> (LeafBlockPower + RootScalePower);
uint8_t root_pos = (index & RootMask) >> LeafBlockPower;
bool root_first = _ch_data[order][root_index].last & MSB;
bool edge_hit = false;
// linear search for the previous transition on the root level
for (int64_t i = root_index; !edge_hit && i >= 0; i--) {
for (int64_t i = root_index; !edge_hit && i >= 0; i--)
{
uint64_t cur_mask = (~0ULL >> (RootScale - root_pos - 1));
do {
uint64_t cur_tog = _ch_data[order][i].tog & cur_mask;
if (cur_tog != 0) {
uint64_t first_edge_pos = bsr64(cur_tog);
uint64_t *lbp = (uint64_t*)_ch_data[order][i].lbp[first_edge_pos];
uint64_t blk_end = ((i << (LeafBlockPower + RootScalePower)) +
(first_edge_pos << LeafBlockPower)) | LeafMask;
index = min(blk_end, index);
if (min_level < ScaleLevel) {
edge_hit = block_pre_edge(lbp, index, last_sample, min_level, sig_index);
} else {
edge_hit = true;
uint64_t inner_tog = _ch_data[order][i].tog & cur_mask;
uint64_t lbp_tog = (_ch_data[order][i].last & cur_mask) ^ ((((uint64_t)root_first << (RootScale - 1)) + (_ch_data[order][i].first >> 1)) & cur_mask);
uint8_t inner_tog_pos = bsr64(inner_tog);
uint8_t lbp_tog_pos = bsr64(lbp_tog);
if (inner_tog != 0)
{
if (lbp_tog != 0) {
// lbp tog before inner tog
edge_hit = lbp_pre_edge(index, i, lbp_tog, lbp_tog_pos, true, inner_tog_pos, last_sample, sig_index);
}
if (first_edge_pos == 0)
if (!edge_hit) {
uint64_t *lbp = (uint64_t*)_ch_data[order][i].lbp[inner_tog_pos];
uint64_t blk_end = ((i << (LeafBlockPower + RootScalePower)) +
(inner_tog_pos << LeafBlockPower)) | LeafMask;
index = min(blk_end, index);
if (min_level < ScaleLevel) {
edge_hit = block_pre_edge(lbp, index, last_sample, min_level, sig_index);
} else {
edge_hit = true;
}
if (inner_tog_pos == 0)
break;
cur_mask = (~0ULL >> (RootScale - inner_tog_pos));
}
}
else if (lbp_tog != 0) {
// lbp tog
edge_hit = lbp_pre_edge(index, i, lbp_tog, lbp_tog_pos, false, 0, last_sample, sig_index);
if (lbp_tog_pos == 0)
break;
cur_mask = (~0ULL >> (RootScale - first_edge_pos));
} else {
}
else {
break;
}
} while (!edge_hit);
}
while (!edge_hit);
root_pos = RootScale - 1;
root_first = _ch_data[order][i].first & LSB;
}
return edge_hit;
}
bool LogicSnapshot::lbp_nxt_edge(uint64_t &index, uint64_t root_index, uint64_t lbp_tog, uint8_t lbp_tog_pos,
bool aft_tog, uint8_t aft_pos, bool last_sample, int sig_index)
{
assert(lbp_tog != 0);
// check last_sample with current index
bool sample = get_sample_self(index, sig_index);
if (sample ^ last_sample)
{
return true;
}
// find edge between lbp
bool edge_hit = false;
uint64_t aft_lbp_start = (root_index << (LeafBlockPower + RootScalePower)) + (aft_pos << LeafBlockPower);
while(lbp_tog_pos <= aft_pos)
{
uint64_t lbp_tog_index = (root_index << (LeafBlockPower + RootScalePower)) + (lbp_tog_pos << LeafBlockPower);
if (lbp_tog_index > aft_lbp_start)
{
edge_hit = false;
break;
}
else if (lbp_tog_index > index)
{
index = lbp_tog_index;
edge_hit = true;
break;
}
lbp_tog_pos++;
lbp_tog &= (~0ULL << lbp_tog_pos);
if ((lbp_tog_pos < Scale) && (lbp_tog != 0))
{
lbp_tog_pos = bsf_folded(lbp_tog);
}
else
{
break;
}
}
uint64_t lbp_edge_index = aft_tog ? aft_lbp_start : aft_lbp_start + (1ULL << LeafBlockPower) - 1;
if (!edge_hit && lbp_edge_index > index)
{
index = lbp_edge_index;
}
return edge_hit;
@@ -934,6 +1042,60 @@ bool LogicSnapshot::block_nxt_edge(uint64_t *lbp, uint64_t &index, uint64_t bloc
return (index <= block_end);
}
bool LogicSnapshot::lbp_pre_edge(uint64_t &index, uint64_t root_index, uint64_t lbp_tog, uint8_t &lbp_tog_pos,
bool pre_tog, uint8_t pre_pos, bool last_sample, int sig_index)
{
assert(lbp_tog != 0);
// check last_sample with current index
bool sample = get_sample_self(index, sig_index);
if (sample ^ last_sample)
{
index++;
return true;
}
// find edge between lbp
bool edge_hit = false;
uint64_t pre_lbp_end = (root_index << (LeafBlockPower + RootScalePower)) + (pre_pos << LeafBlockPower) + (1ULL << LeafBlockPower) - 1;
do
{
uint64_t lbp_tog_index = (root_index << (LeafBlockPower + RootScalePower)) + (lbp_tog_pos << LeafBlockPower) + (1ULL << LeafBlockPower) - 1;
if (lbp_tog_index < pre_lbp_end)
{
edge_hit = false;
break;
}
else if (lbp_tog_index < index)
{
index = lbp_tog_index + 1;
edge_hit = true;
break;
}
if (lbp_tog_pos > 0)
{
lbp_tog_pos--;
lbp_tog &= (~0ULL >> (Scale - lbp_tog_pos - 1));
lbp_tog_pos = (lbp_tog != 0) ? bsr64(lbp_tog) : 0;
}
else
{
lbp_tog = 0;
}
}
while (lbp_tog != 0 && lbp_tog_pos >= pre_pos);
uint64_t lbp_edge_index = pre_tog ? pre_lbp_end : pre_lbp_end + 1 - (1ULL << LeafBlockPower);
if (!edge_hit && lbp_edge_index < index)
{
index = lbp_edge_index;
}
return edge_hit;
}
bool LogicSnapshot::block_pre_edge(uint64_t *lbp, uint64_t &index, bool last_sample,
unsigned int min_level, int sig_index)
{
@@ -1241,7 +1403,7 @@ uint8_t *LogicSnapshot::get_block_buf(int block_index, int sig_index, bool &samp
uint8_t *lbp = (uint8_t*)_ch_data[order][index].lbp[pos];
if (lbp == NULL)
sample = (_ch_data[order][index].value & 1ULL << pos) != 0;
sample = (_ch_data[order][index].first & 1ULL << pos) != 0;
if (lbp != NULL && _loop_offset > 0 && block_index0 == 0)
{
@@ -1281,7 +1443,8 @@ void LogicSnapshot::move_first_node_to_last()
}
rn.tog = 0;
rn.value = 0;
rn.first = 0;
rn.last = 0;
_ch_data[i].push_back(rn);
}
@@ -1314,7 +1477,8 @@ void LogicSnapshot::free_decode_lpb(void *lbp)
}
void LogicSnapshot::free_head_blocks(int count)
{
{
assert(count < Scale);
assert(count > 0);
for (int i = 0; i < (int)_channel_num; i++)
@@ -1326,8 +1490,9 @@ void LogicSnapshot::free_head_blocks(int count)
}
_ch_data[i][0].tog = (_ch_data[i][0].tog >> count) << count;
_ch_data[i][0].value = (_ch_data[i][0].value >> count) << count;
}
_ch_data[i][0].first = (_ch_data[i][0].first >> count) << count;
_ch_data[i][0].last = (_ch_data[i][0].last >> count) << count;
}
}
_lst_free_block_index = count;
}

View File

@@ -65,11 +65,15 @@ private:
static const uint64_t LevelMask[ScaleLevel];
static const uint64_t LevelOffset[ScaleLevel];
static const uint64_t MSB = (1ULL << (Scale - 1));
static const uint64_t LSB = (1ULL);
private:
struct RootNode
{
uint64_t tog;
uint64_t value;
uint64_t first;
uint64_t last;
void *lbp[Scale];
};
@@ -163,15 +167,21 @@ private:
void append_cross_payload(const sr_datafeed_logic &logic);
bool lbp_nxt_edge(uint64_t &index, uint64_t root_index, uint64_t lbp_tog, uint8_t lbp_tog_pos,
bool aft_tog, uint8_t aft_pos, bool last_sample, int sig_index);
bool block_nxt_edge(uint64_t *lbp, uint64_t &index, uint64_t block_end, bool last_sample,
unsigned int min_level);
bool lbp_pre_edge(uint64_t &index, uint64_t root_index, uint64_t lbp_tog, uint8_t &lbp_tog_pos,
bool pre_tog, uint8_t pre_pos, bool last_sample, int sig_index);
bool block_pre_edge(uint64_t *lbp, uint64_t &index, bool last_sample,
unsigned int min_level, int sig_index);
inline uint64_t bsf_folded (uint64_t bb)
inline uint8_t bsf_folded (uint64_t bb)
{
static const int lsb_64_table[64] = {
static const uint8_t lsb_64_table[64] = {
63, 30, 3, 32, 59, 14, 11, 33,
60, 24, 50, 9, 55, 19, 21, 34,
61, 29, 2, 53, 51, 23, 41, 18,
@@ -187,9 +197,9 @@ private:
return lsb_64_table[folded * 0x78291ACF >> 26];
}
inline int bsr32(uint32_t bb)
inline uint8_t bsr32(uint32_t bb)
{
static const char msb_256_table[256] = {
static const uint8_t msb_256_table[256] = {
0, 0, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3,
4, 4, 4, 4, 4, 4, 4, 4,4, 4, 4, 4,4, 4, 4, 4,
5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
@@ -200,7 +210,7 @@ private:
7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
};
int result = 0;
uint8_t result = 0;
if (bb > 0xFFFF) {
bb >>= 16;
@@ -214,7 +224,7 @@ private:
return (result + msb_256_table[bb]);
}
inline uint64_t bsr64(uint64_t bb)
inline uint8_t bsr64(uint64_t bb)
{
const uint32_t hb = bb >> 32;
return hb ? 32 + bsr32((uint32_t)hb) : bsr32((uint32_t)bb);

View File

@@ -139,7 +139,7 @@ void LogicSignal::paint_mid_align(QPainter &p, int left, int right, QColor fore,
uint16_t width = right - left;
const double start = offset * samples_per_pixel;
const double end = (offset + width + 1) * samples_per_pixel;
const uint64_t end_index = min(max((int64_t)ceil(end), (int64_t)0), last_sample);
const uint64_t end_index = min(max((int64_t)floor(end), (int64_t)0), last_sample);
const uint64_t start_index = max((uint64_t)floor(start), (uint64_t)0);
if (start_index > end_index)