Coverage Report

Created: 2026-08-14 10:22

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/libreoffice/basegfx/source/tools/systemdependentdata.cxx
Line
Count
Source
1
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2
/*
3
 * This file is part of the LibreOffice project.
4
 *
5
 * This Source Code Form is subject to the terms of the Mozilla Public
6
 * License, v. 2.0. If a copy of the MPL was not distributed with this
7
 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8
 */
9
10
#include <basegfx/utils/systemdependentdata.hxx>
11
#include <config_fuzzers.h>
12
#include <math.h>
13
14
namespace basegfx
15
{
16
    SystemDependentDataManager::SystemDependentDataManager()
17
2
    {
18
2
    }
19
20
    SystemDependentDataManager::~SystemDependentDataManager()
21
2
    {
22
2
    }
23
} // namespace basegfx
24
25
namespace basegfx
26
{
27
    SystemDependentData::SystemDependentData(
28
        SystemDependentDataManager& rSystemDependentDataManager,
29
        SDD_Type aSystemDependentDataType)
30
2.17M
    :   mrSystemDependentDataManager(rSystemDependentDataManager)
31
2.17M
    , maSystemDependentDataType(aSystemDependentDataType)
32
2.17M
    , mnCalculatedCycles(0)
33
2.17M
    {
34
2.17M
    }
35
36
    SystemDependentData::~SystemDependentData()
37
2.17M
    {
38
2.17M
    }
39
40
    sal_uInt32 SystemDependentData::calculateCombinedHoldCyclesInSeconds() const
41
2.17M
    {
42
2.17M
#if ENABLE_FUZZERS
43
2.17M
        return 0;
44
0
#endif
45
46
        // already set, use it
47
0
        if(0 != mnCalculatedCycles)
48
0
            return mnCalculatedCycles;
49
50
        // get size in bytes as base for estimation
51
0
        const sal_Int64 nBytes(estimateUsageInBytes());
52
53
        // tdf#129845 as indicator for no need to buffer trivial data, stay at and
54
        // return zero. As border, use 450 bytes. For polygons, this means to buffer
55
        // starting with ca. 50 points (GDIPLUS uses 9 bytes per coordinate). For
56
        // Bitmap data this means to more or less always buffer (as it was before).
57
        // Note that this is the method for all Buffered data, independent of
58
        // graphic target, so it is possible to refine that if needed in the
59
        // system-dependent parts of impl (see getOrCreateCairoSurfaceHelper). It
60
        // is also possible to make calculateCombinedHoldCyclesInSeconds virtual
61
        // and override for your needs.
62
0
        if (nBytes < 450)
63
0
            return mnCalculatedCycles;
64
65
        // We have seen that for very huge images the hold time was too short, e.g.
66
        // for a very huge bitmap (see fHugeDataInBytes below) it was about 20s. This
67
        // is not enough, we have learned that we need to hold huge data longer.
68
        // In the impl before I took the memory aspect more into account, so I used
69
        // sqrt() to have less HoldTime the bigger the nBytes gets by using a flattening
70
        // curve. With having identified that remain time is important for those cases,
71
        // we can go back to linear. This means that we can explicitly choose a
72
        // HoldTime, get a factor and simply apply that to all buffered data.
73
        // Setup:
74
        //  fHugeDataInBytes -> 300000000
75
        //  fHugeTimeToHoldInSeconds -> 1200
76
        //  fTimeToHoldInSecondsPerByte -> 0.000004
77
        // Example outcome (for implied raw BitmapData):
78
        //  320x200 -> 1.024s
79
        //  800x600 -> 7.68s
80
        //  1600x1200 -> 30.72s
81
        //  15000x5000 -> 1200s (as targeted)
82
0
        constexpr double fHugeDataInBytes(15000*5000*4);
83
0
        constexpr double fHugeTimeToHoldInSeconds(20 * 60);
84
0
        constexpr double fTimeToHoldInSecondsPerByte(fHugeTimeToHoldInSeconds/fHugeDataInBytes);
85
86
        // set locally (once, on-demand created, non-zero)
87
0
        mnCalculatedCycles = static_cast<sal_uInt32>(1.0 + nBytes * fTimeToHoldInSecondsPerByte);
88
89
0
        return mnCalculatedCycles;
90
0
    }
91
92
    sal_Int64 SystemDependentData::estimateUsageInBytes() const
93
0
    {
94
        // default implementation has no idea
95
0
        return 0;
96
0
    }
97
} // namespace basegfx
98
99
namespace basegfx
100
{
101
    SystemDependentDataHolder::SystemDependentDataHolder()
102
8.10M
    {
103
8.10M
    }
104
105
    SystemDependentDataHolder::~SystemDependentDataHolder()
106
8.10M
    {
107
8.10M
        for(const auto& candidate : maSystemDependentReferences)
108
0
        {
109
0
            basegfx::SystemDependentData_SharedPtr aData(candidate.second.lock());
110
111
0
            if(aData)
112
0
            {
113
0
                aData->getSystemDependentDataManager().endUsage(aData);
114
0
            }
115
0
        }
116
8.10M
    }
117
118
    void SystemDependentDataHolder::addOrReplaceSystemDependentData(basegfx::SystemDependentData_SharedPtr& rData)
119
0
    {
120
0
        auto result(maSystemDependentReferences.find(rData->getSystemDependentDataType()));
121
122
0
        if(result != maSystemDependentReferences.end())
123
0
        {
124
0
            basegfx::SystemDependentData_SharedPtr aData(result->second.lock());
125
126
0
            if(aData)
127
0
            {
128
0
                aData->getSystemDependentDataManager().endUsage(aData);
129
0
            }
130
131
0
            maSystemDependentReferences.erase(result);
132
0
            result = maSystemDependentReferences.end();
133
0
        }
134
135
0
        maSystemDependentReferences[rData->getSystemDependentDataType()] = rData;
136
0
        rData->getSystemDependentDataManager().startUsage(rData);
137
0
    }
138
139
    SystemDependentData_SharedPtr SystemDependentDataHolder::getSystemDependentData(SDD_Type aType) const
140
177k
    {
141
177k
        basegfx::SystemDependentData_SharedPtr aRetval;
142
177k
        auto result(maSystemDependentReferences.find(aType));
143
144
177k
        if(result != maSystemDependentReferences.end())
145
0
        {
146
0
            aRetval = result->second.lock();
147
148
0
            if(aRetval)
149
0
            {
150
0
                aRetval->getSystemDependentDataManager().touchUsage(aRetval);
151
0
            }
152
0
            else
153
0
            {
154
0
                const_cast< SystemDependentDataHolder* >(this)->maSystemDependentReferences.erase(result);
155
0
            }
156
0
        }
157
158
177k
        return aRetval;
159
177k
    }
160
} // namespace basegfx
161
162
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */