RemoteDrawingEngine: Reduce RP_READ_BITMAP result timeout.
[haiku.git] / src / apps / activitymonitor / DataSource.cpp
blob3adadebcf50ed3a64b7b90aad47243941cdba647
1 /*
2 * Copyright 2008-2009, Axel Dörfler, axeld@pinc-software.de.
3 * Distributed under the terms of the MIT License.
4 */
7 #include "DataSource.h"
9 #include <stdio.h>
10 #include <stdint.h>
12 #include <Catalog.h>
13 #include <OS.h>
14 #include <String.h>
15 #include <StringForRate.h>
17 #include "SystemInfo.h"
19 #undef B_TRANSLATION_CONTEXT
20 #define B_TRANSLATION_CONTEXT "DataSource"
23 const DataSource* kSources[] = {
24 new UsedMemoryDataSource(),
25 new CachedMemoryDataSource(),
26 new SwapSpaceDataSource(),
27 new PageFaultsDataSource(),
28 new CPUUsageDataSource(),
29 new CPUCombinedUsageDataSource(),
30 new NetworkUsageDataSource(true),
31 new NetworkUsageDataSource(false),
32 new BlockCacheDataSource(),
33 new SemaphoresDataSource(),
34 new PortsDataSource(),
35 new ThreadsDataSource(),
36 new TeamsDataSource(),
37 new RunningAppsDataSource(),
38 new ClipboardSizeDataSource(false),
39 new ClipboardSizeDataSource(true),
40 new MediaNodesDataSource()
42 const size_t kSourcesCount = sizeof(kSources) / sizeof(kSources[0]);
45 DataSource::DataSource(int64 initialMin, int64 initialMax)
47 fMinimum(initialMin),
48 fMaximum(initialMax),
49 fInterval(1000000LL),
50 fColor((rgb_color){200, 0, 0})
55 DataSource::DataSource()
57 fMinimum(0),
58 fMaximum(100),
59 fInterval(1000000LL),
60 fColor((rgb_color){200, 0, 0})
65 DataSource::DataSource(const DataSource& other)
67 fMinimum = other.fMinimum;
68 fMaximum = other.fMaximum;
69 fInterval = other.fInterval;
70 fColor = other.fColor;
74 DataSource::~DataSource()
79 DataSource*
80 DataSource::Copy() const
82 return NULL;
83 // this class cannot be copied
87 DataSource*
88 DataSource::CopyForCPU(int32 cpu) const
90 return Copy();
94 int64
95 DataSource::Minimum() const
97 return fMinimum;
101 int64
102 DataSource::Maximum() const
104 return fMaximum;
108 bigtime_t
109 DataSource::RefreshInterval() const
111 return fInterval;
115 void
116 DataSource::SetLimits(int64 min, int64 max)
118 fMinimum = min;
119 fMaximum = max;
123 void
124 DataSource::SetRefreshInterval(bigtime_t interval)
126 fInterval = interval;
130 void
131 DataSource::SetColor(rgb_color color)
133 fColor = color;
137 int64
138 DataSource::NextValue(SystemInfo& info)
140 return 0;
144 void
145 DataSource::Print(BString& text, int64 value) const
147 text = "";
148 text << value;
152 const char*
153 DataSource::ShortLabel() const
155 return Label();
159 const char*
160 DataSource::Name() const
162 return Label();
166 const char*
167 DataSource::Label() const
169 return "";
173 const char*
174 DataSource::Unit() const
176 return "";
180 rgb_color
181 DataSource::Color() const
183 return fColor;
187 bool
188 DataSource::AdaptiveScale() const
190 return false;
194 scale_type
195 DataSource::ScaleType() const
197 return kNoScale;
201 int32
202 DataSource::CPU() const
204 return 0;
208 bool
209 DataSource::PerCPU() const
211 return false;
215 bool
216 DataSource::MultiCPUOnly() const
218 return false;
222 bool
223 DataSource::Primary() const
225 return false;
229 /*static*/ int32
230 DataSource::CountSources()
232 return kSourcesCount;
236 /*static*/ const DataSource*
237 DataSource::SourceAt(int32 index)
239 if (index >= (int32)kSourcesCount || index < 0)
240 return NULL;
242 return kSources[index];
246 /*static*/ const DataSource*
247 DataSource::FindSource(const char* internalName)
249 for (uint32 i = 0; i < kSourcesCount; i++) {
250 const DataSource* source = kSources[i];
251 if (!strcmp(source->InternalName(), internalName))
252 return source;
255 return NULL;
259 /*static*/ int32
260 DataSource::IndexOf(const DataSource* source)
262 const char* name = source->Name();
264 for (uint32 i = 0; i < kSourcesCount; i++) {
265 if (!strcmp(kSources[i]->Name(), name))
266 return i;
269 return -1;
273 // #pragma mark -
276 MemoryDataSource::MemoryDataSource()
278 SystemInfo info;
280 fMinimum = 0;
281 fMaximum = info.MaxMemory();
285 MemoryDataSource::~MemoryDataSource()
290 void
291 MemoryDataSource::Print(BString& text, int64 value) const
293 char buffer[32];
294 snprintf(buffer, sizeof(buffer), B_TRANSLATE("%.1f MiB"), value / 1048576.0);
296 text = buffer;
300 const char*
301 MemoryDataSource::Unit() const
303 return B_TRANSLATE("MiB");
307 // #pragma mark -
310 UsedMemoryDataSource::UsedMemoryDataSource()
315 UsedMemoryDataSource::~UsedMemoryDataSource()
320 DataSource*
321 UsedMemoryDataSource::Copy() const
323 return new UsedMemoryDataSource(*this);
327 int64
328 UsedMemoryDataSource::NextValue(SystemInfo& info)
330 return info.UsedMemory();
334 const char*
335 UsedMemoryDataSource::InternalName() const
337 return "Used memory";
341 const char*
342 UsedMemoryDataSource::Label() const
344 return B_TRANSLATE("Used memory");
348 const char*
349 UsedMemoryDataSource::ShortLabel() const
351 return B_TRANSLATE("Memory");
355 bool
356 UsedMemoryDataSource::Primary() const
358 return true;
362 // #pragma mark -
365 CachedMemoryDataSource::CachedMemoryDataSource()
367 fColor = (rgb_color){0, 200, 0};
371 CachedMemoryDataSource::~CachedMemoryDataSource()
376 DataSource*
377 CachedMemoryDataSource::Copy() const
379 return new CachedMemoryDataSource(*this);
383 int64
384 CachedMemoryDataSource::NextValue(SystemInfo& info)
386 return info.CachedMemory();
390 const char*
391 CachedMemoryDataSource::InternalName() const
393 return "Cached memory";
397 const char*
398 CachedMemoryDataSource::Label() const
400 return B_TRANSLATE("Cached memory");
404 const char*
405 CachedMemoryDataSource::ShortLabel() const
407 return B_TRANSLATE("Cache");
411 bool
412 CachedMemoryDataSource::Primary() const
414 return true;
418 // #pragma mark -
421 SwapSpaceDataSource::SwapSpaceDataSource()
423 SystemInfo info;
425 fColor = (rgb_color){0, 120, 0};
426 fMaximum = info.MaxSwapSpace();
430 SwapSpaceDataSource::~SwapSpaceDataSource()
435 DataSource*
436 SwapSpaceDataSource::Copy() const
438 return new SwapSpaceDataSource(*this);
442 int64
443 SwapSpaceDataSource::NextValue(SystemInfo& info)
445 return info.UsedSwapSpace();
449 const char*
450 SwapSpaceDataSource::InternalName() const
452 return "Swap space";
456 const char*
457 SwapSpaceDataSource::Label() const
459 return B_TRANSLATE("Swap space");
463 const char*
464 SwapSpaceDataSource::ShortLabel() const
466 return B_TRANSLATE("Swap");
470 bool
471 SwapSpaceDataSource::Primary() const
473 return true;
477 // #pragma mark -
480 BlockCacheDataSource::BlockCacheDataSource()
482 fColor = (rgb_color){0, 0, 120};
486 BlockCacheDataSource::~BlockCacheDataSource()
491 DataSource*
492 BlockCacheDataSource::Copy() const
494 return new BlockCacheDataSource(*this);
498 int64
499 BlockCacheDataSource::NextValue(SystemInfo& info)
501 return info.BlockCacheMemory();
505 const char*
506 BlockCacheDataSource::InternalName() const
508 return "Block cache memory";
512 const char*
513 BlockCacheDataSource::Label() const
515 return B_TRANSLATE("Block cache memory");
519 const char*
520 BlockCacheDataSource::ShortLabel() const
522 return B_TRANSLATE("Block cache");
526 // #pragma mark -
529 SemaphoresDataSource::SemaphoresDataSource()
531 SystemInfo info;
533 fMinimum = 0;
534 fMaximum = info.MaxSemaphores();
536 fColor = (rgb_color){100, 200, 100};
540 SemaphoresDataSource::~SemaphoresDataSource()
545 DataSource*
546 SemaphoresDataSource::Copy() const
548 return new SemaphoresDataSource(*this);
552 int64
553 SemaphoresDataSource::NextValue(SystemInfo& info)
555 return info.UsedSemaphores();
559 const char*
560 SemaphoresDataSource::InternalName() const
562 return "Semaphores";
566 const char*
567 SemaphoresDataSource::Label() const
569 return B_TRANSLATE("Semaphores");
573 const char*
574 SemaphoresDataSource::ShortLabel() const
576 return B_TRANSLATE("Sems");
580 bool
581 SemaphoresDataSource::AdaptiveScale() const
583 return true;
587 // #pragma mark -
590 PortsDataSource::PortsDataSource()
592 SystemInfo info;
594 fMinimum = 0;
595 fMaximum = info.MaxPorts();
597 fColor = (rgb_color){180, 200, 180};
601 PortsDataSource::~PortsDataSource()
606 DataSource*
607 PortsDataSource::Copy() const
609 return new PortsDataSource(*this);
613 int64
614 PortsDataSource::NextValue(SystemInfo& info)
616 return info.UsedPorts();
620 const char*
621 PortsDataSource::InternalName() const
623 return "Ports";
627 const char*
628 PortsDataSource::Label() const
630 return B_TRANSLATE("Ports");
634 bool
635 PortsDataSource::AdaptiveScale() const
637 return true;
641 // #pragma mark -
644 ThreadsDataSource::ThreadsDataSource()
646 SystemInfo info;
648 fMinimum = 0;
649 fMaximum = info.MaxThreads();
651 fColor = (rgb_color){0, 0, 200};
655 ThreadsDataSource::~ThreadsDataSource()
660 DataSource*
661 ThreadsDataSource::Copy() const
663 return new ThreadsDataSource(*this);
667 int64
668 ThreadsDataSource::NextValue(SystemInfo& info)
670 return info.UsedThreads();
674 const char*
675 ThreadsDataSource::InternalName() const
677 return "Threads";
681 const char*
682 ThreadsDataSource::Label() const
684 return B_TRANSLATE("Threads");
688 bool
689 ThreadsDataSource::AdaptiveScale() const
691 return true;
695 // #pragma mark -
698 TeamsDataSource::TeamsDataSource()
700 SystemInfo info;
702 fMinimum = 0;
703 fMaximum = info.MaxTeams();
705 fColor = (rgb_color){0, 150, 255};
709 TeamsDataSource::~TeamsDataSource()
714 DataSource*
715 TeamsDataSource::Copy() const
717 return new TeamsDataSource(*this);
721 int64
722 TeamsDataSource::NextValue(SystemInfo& info)
724 return info.UsedTeams();
728 const char*
729 TeamsDataSource::InternalName() const
731 return "Teams";
735 const char*
736 TeamsDataSource::Label() const
738 return B_TRANSLATE("Teams");
742 bool
743 TeamsDataSource::AdaptiveScale() const
745 return true;
749 // #pragma mark -
752 RunningAppsDataSource::RunningAppsDataSource()
754 SystemInfo info;
756 fMinimum = 0;
757 fMaximum = info.MaxRunningApps();
759 fColor = (rgb_color){100, 150, 255};
763 RunningAppsDataSource::~RunningAppsDataSource()
768 DataSource*
769 RunningAppsDataSource::Copy() const
771 return new RunningAppsDataSource(*this);
775 int64
776 RunningAppsDataSource::NextValue(SystemInfo& info)
778 return info.UsedRunningApps();
782 const char*
783 RunningAppsDataSource::InternalName() const
785 return "Running applications";
789 const char*
790 RunningAppsDataSource::Label() const
792 return B_TRANSLATE("Running applications");
796 const char*
797 RunningAppsDataSource::ShortLabel() const
799 return B_TRANSLATE("Apps");
803 bool
804 RunningAppsDataSource::AdaptiveScale() const
806 return true;
810 // #pragma mark -
813 CPUUsageDataSource::CPUUsageDataSource(int32 cpu)
815 fPreviousActive(0),
816 fPreviousTime(0)
818 fMinimum = 0;
819 fMaximum = 1000;
821 _SetCPU(cpu);
825 CPUUsageDataSource::CPUUsageDataSource(const CPUUsageDataSource& other)
826 : DataSource(other)
828 fPreviousActive = other.fPreviousActive;
829 fPreviousTime = other.fPreviousTime;
830 fCPU = other.fCPU;
831 fLabel = other.fLabel;
832 fShortLabel = other.fShortLabel;
836 CPUUsageDataSource::~CPUUsageDataSource()
841 DataSource*
842 CPUUsageDataSource::Copy() const
844 return new CPUUsageDataSource(*this);
848 DataSource*
849 CPUUsageDataSource::CopyForCPU(int32 cpu) const
851 CPUUsageDataSource* copy = new CPUUsageDataSource(*this);
852 copy->_SetCPU(cpu);
854 return copy;
858 void
859 CPUUsageDataSource::Print(BString& text, int64 value) const
861 char buffer[32];
862 snprintf(buffer, sizeof(buffer), "%.1f%%", value / 10.0);
864 text = buffer;
868 int64
869 CPUUsageDataSource::NextValue(SystemInfo& info)
871 bigtime_t active = info.CPUActiveTime(fCPU);
873 int64 percent = int64(1000.0 * (active - fPreviousActive)
874 / (info.Time() - fPreviousTime));
875 if (percent < 0)
876 percent = 0;
877 if (percent > 1000)
878 percent = 1000;
880 fPreviousActive = active;
881 fPreviousTime = info.Time();
883 return percent;
887 const char*
888 CPUUsageDataSource::Label() const
890 return fLabel.String();
894 const char*
895 CPUUsageDataSource::ShortLabel() const
897 return fShortLabel.String();
901 const char*
902 CPUUsageDataSource::InternalName() const
904 return "CPU usage";
908 const char*
909 CPUUsageDataSource::Name() const
911 return B_TRANSLATE("CPU usage");
915 int32
916 CPUUsageDataSource::CPU() const
918 return fCPU;
922 bool
923 CPUUsageDataSource::PerCPU() const
925 return true;
929 bool
930 CPUUsageDataSource::Primary() const
932 return true;
936 void
937 CPUUsageDataSource::_SetCPU(int32 cpu)
939 fCPU = cpu;
940 fLabel = B_TRANSLATE("CPU");
941 if (SystemInfo().CPUCount() > 1)
942 fLabel << " " << cpu + 1;
943 fShortLabel = fLabel;
945 fLabel << " " << B_TRANSLATE("usage");
947 const rgb_color kColors[] = {
948 // TODO: find some better defaults...
949 {200, 0, 200},
950 {0, 200, 200},
951 {80, 80, 80},
952 {230, 150, 50},
953 {255, 0, 0},
954 {0, 255, 0},
955 {0, 0, 255},
956 {0, 150, 230}
958 const uint32 kNumColors = sizeof(kColors) / sizeof(kColors[0]);
960 fColor = kColors[cpu % kNumColors];
964 // #pragma mark -
967 CPUCombinedUsageDataSource::CPUCombinedUsageDataSource()
969 fPreviousActive(0),
970 fPreviousTime(0)
972 fMinimum = 0;
973 fMaximum = 1000;
975 fColor = (rgb_color){200, 200, 0};
979 CPUCombinedUsageDataSource::CPUCombinedUsageDataSource(
980 const CPUCombinedUsageDataSource& other)
981 : DataSource(other)
983 fPreviousActive = other.fPreviousActive;
984 fPreviousTime = other.fPreviousTime;
988 CPUCombinedUsageDataSource::~CPUCombinedUsageDataSource()
993 DataSource*
994 CPUCombinedUsageDataSource::Copy() const
996 return new CPUCombinedUsageDataSource(*this);
1000 void
1001 CPUCombinedUsageDataSource::Print(BString& text, int64 value) const
1003 char buffer[32];
1004 snprintf(buffer, sizeof(buffer), "%.1f%%", value / 10.0);
1006 text = buffer;
1010 int64
1011 CPUCombinedUsageDataSource::NextValue(SystemInfo& info)
1013 int32 running = 0;
1014 bigtime_t active = 0;
1016 for (uint32 cpu = 0; cpu < info.CPUCount(); cpu++) {
1017 active += info.CPUActiveTime(cpu);
1018 running++;
1019 // TODO: take disabled CPUs into account
1022 int64 percent = int64(1000.0 * (active - fPreviousActive)
1023 / (running * (info.Time() - fPreviousTime)));
1024 if (percent < 0)
1025 percent = 0;
1026 if (percent > 1000)
1027 percent = 1000;
1029 fPreviousActive = active;
1030 fPreviousTime = info.Time();
1032 return percent;
1036 const char*
1037 CPUCombinedUsageDataSource::Label() const
1039 return B_TRANSLATE("CPU usage");
1043 const char*
1044 CPUCombinedUsageDataSource::ShortLabel() const
1046 return B_TRANSLATE("CPU");
1050 const char*
1051 CPUCombinedUsageDataSource::InternalName() const
1053 return "CPU usage (combined)";
1057 const char*
1058 CPUCombinedUsageDataSource::Name() const
1060 return B_TRANSLATE("CPU usage (combined)");
1064 bool
1065 CPUCombinedUsageDataSource::MultiCPUOnly() const
1067 return true;
1071 bool
1072 CPUCombinedUsageDataSource::Primary() const
1074 return true;
1078 // #pragma mark -
1081 PageFaultsDataSource::PageFaultsDataSource()
1083 fPreviousFaults(0),
1084 fPreviousTime(0)
1086 SystemInfo info;
1087 NextValue(info);
1089 fMinimum = 0;
1090 fMaximum = 1000000000LL;
1092 fColor = (rgb_color){200, 0, 150, 0};
1096 PageFaultsDataSource::PageFaultsDataSource(const PageFaultsDataSource& other)
1097 : DataSource(other)
1099 fPreviousFaults = other.fPreviousFaults;
1100 fPreviousTime = other.fPreviousTime;
1104 PageFaultsDataSource::~PageFaultsDataSource()
1109 DataSource*
1110 PageFaultsDataSource::Copy() const
1112 return new PageFaultsDataSource(*this);
1116 void
1117 PageFaultsDataSource::Print(BString& text, int64 value) const
1119 char buffer[32];
1120 snprintf(buffer, sizeof(buffer), B_TRANSLATE("%.1f faults/s"),
1121 value / 1024.0);
1123 text = buffer;
1127 int64
1128 PageFaultsDataSource::NextValue(SystemInfo& info)
1130 uint64 faults = info.PageFaults();
1132 int64 faultsPerSecond = uint64(1024 * double(faults - fPreviousFaults)
1133 / (info.Time() - fPreviousTime) * 1000000.0);
1135 fPreviousFaults = faults;
1136 fPreviousTime = info.Time();
1138 return faultsPerSecond;
1142 const char*
1143 PageFaultsDataSource::Label() const
1145 return B_TRANSLATE("Page faults");
1149 const char*
1150 PageFaultsDataSource::ShortLabel() const
1152 return B_TRANSLATE("P-faults");
1156 const char*
1157 PageFaultsDataSource::InternalName() const
1159 return "Page faults";
1163 const char*
1164 PageFaultsDataSource::Name() const
1166 return B_TRANSLATE("Page faults");
1170 bool
1171 PageFaultsDataSource::AdaptiveScale() const
1173 return true;
1177 bool
1178 PageFaultsDataSource::Primary() const
1180 return false;
1184 // #pragma mark -
1187 NetworkUsageDataSource::NetworkUsageDataSource(bool in)
1189 fIn(in),
1190 fPreviousBytes(0),
1191 fPreviousTime(0)
1193 SystemInfo info;
1194 NextValue(info);
1196 fMinimum = 0;
1197 fMaximum = 1000000000LL;
1199 fColor = fIn ? (rgb_color){200, 150, 0} : (rgb_color){200, 220, 0};
1203 NetworkUsageDataSource::NetworkUsageDataSource(
1204 const NetworkUsageDataSource& other)
1205 : DataSource(other)
1207 fIn = other.fIn;
1208 fPreviousBytes = other.fPreviousBytes;
1209 fPreviousTime = other.fPreviousTime;
1213 NetworkUsageDataSource::~NetworkUsageDataSource()
1218 DataSource*
1219 NetworkUsageDataSource::Copy() const
1221 return new NetworkUsageDataSource(*this);
1225 void
1226 NetworkUsageDataSource::Print(BString& text, int64 value) const
1228 char buffer[32];
1229 string_for_rate(value, buffer, sizeof(buffer));
1231 text = buffer;
1235 int64
1236 NetworkUsageDataSource::NextValue(SystemInfo& info)
1238 uint64 transferred = fIn ? info.NetworkReceived() : info.NetworkSent();
1240 int64 bytesPerSecond = uint64(double(transferred - fPreviousBytes)
1241 / (info.Time() - fPreviousTime) * 1000000.0);
1243 fPreviousBytes = transferred;
1244 fPreviousTime = info.Time();
1246 return bytesPerSecond;
1250 const char*
1251 NetworkUsageDataSource::Label() const
1253 return fIn ? B_TRANSLATE("Receiving") : B_TRANSLATE("Sending");
1257 const char*
1258 NetworkUsageDataSource::ShortLabel() const
1260 return fIn ? B_TRANSLATE_COMMENT("RX", "Shorter version for Receiving.") :
1261 B_TRANSLATE_COMMENT("TX", "Shorter version for Sending");
1265 const char*
1266 NetworkUsageDataSource::InternalName() const
1268 return fIn ? "Network receive" : "Network send";
1272 const char*
1273 NetworkUsageDataSource::Name() const
1275 return fIn ? B_TRANSLATE("Network receive") : B_TRANSLATE("Network send");
1279 bool
1280 NetworkUsageDataSource::AdaptiveScale() const
1282 return true;
1286 scale_type
1287 NetworkUsageDataSource::ScaleType() const
1289 return kBytePerSecondScale;
1293 bool
1294 NetworkUsageDataSource::Primary() const
1296 return true;
1300 // #pragma mark -
1303 ClipboardSizeDataSource::ClipboardSizeDataSource(bool text)
1305 fMinimum = 0;
1306 fMaximum = UINT32_MAX;
1307 fText = text;
1309 fColor = (rgb_color){0, 150, 255};
1313 ClipboardSizeDataSource::ClipboardSizeDataSource(
1314 const ClipboardSizeDataSource& other)
1315 : DataSource(other)
1317 fText = other.fText;
1321 ClipboardSizeDataSource::~ClipboardSizeDataSource()
1326 DataSource*
1327 ClipboardSizeDataSource::Copy() const
1329 return new ClipboardSizeDataSource(*this);
1333 int64
1334 ClipboardSizeDataSource::NextValue(SystemInfo& info)
1336 if (fText)
1337 return info.ClipboardTextSize()/* / 1024*/;
1338 return info.ClipboardSize()/* / 1024*/;
1342 const char*
1343 ClipboardSizeDataSource::InternalName() const
1345 return fText ? "Text clipboard size" : "Raw clipboard size";
1349 const char*
1350 ClipboardSizeDataSource::Label() const
1352 return fText ? B_TRANSLATE("Text clipboard")
1353 : B_TRANSLATE("Raw clipboard");
1357 const char*
1358 ClipboardSizeDataSource::Unit() const
1360 return "bytes"/*"KB"*/;
1364 bool
1365 ClipboardSizeDataSource::AdaptiveScale() const
1367 return true;
1371 // #pragma mark -
1374 MediaNodesDataSource::MediaNodesDataSource()
1376 SystemInfo info;
1378 fMinimum = 0;
1379 fMaximum = INT32_MAX;
1381 fColor = (rgb_color){255, 150, 225};
1385 MediaNodesDataSource::~MediaNodesDataSource()
1390 DataSource*
1391 MediaNodesDataSource::Copy() const
1393 return new MediaNodesDataSource(*this);
1397 int64
1398 MediaNodesDataSource::NextValue(SystemInfo& info)
1400 return info.MediaNodes();
1404 const char*
1405 MediaNodesDataSource::InternalName() const
1407 return "Media nodes";
1411 const char*
1412 MediaNodesDataSource::Label() const
1414 return B_TRANSLATE("Media nodes");
1418 bool
1419 MediaNodesDataSource::AdaptiveScale() const
1421 return true;