Use an OptionSet<> for GraphicsLayerPaintingPhase
[WebKit-https.git] / Source / WebCore / page / linux / ResourceUsageOverlayLinux.cpp
1 /*
2  * Copyright (C) 2017 Igalia S.L.
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions
6  * are met:
7  * 1. Redistributions of source code must retain the above copyright
8  *    notice, this list of conditions and the following disclaimer.
9  * 2. Redistributions in binary form must reproduce the above copyright
10  *    notice, this list of conditions and the following disclaimer in the
11  *    documentation and/or other materials provided with the distribution.
12  *
13  * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
14  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
15  * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16  * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
17  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
18  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
19  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
20  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
21  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
22  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
23  * THE POSSIBILITY OF SUCH DAMAGE.
24  */
25
26 #include "config.h"
27 #include "ResourceUsageOverlay.h"
28
29 #if ENABLE(RESOURCE_USAGE) && OS(LINUX)
30
31 #include "Chrome.h"
32 #include "ChromeClient.h"
33 #include "CommonVM.h"
34 #include "GraphicsContext.h"
35 #include "Page.h"
36 #include "RenderTheme.h"
37 #include "ResourceUsageThread.h"
38 #include <JavaScriptCore/VM.h>
39 #include <wtf/text/StringConcatenateNumbers.h>
40
41 namespace WebCore {
42
43 static ResourceUsageData gData;
44
45 static String cpuUsageString(float cpuUsage)
46 {
47     if (cpuUsage < 0)
48         return "<unknown>"_s;
49     return makeString(FormattedNumber::fixedWidth(cpuUsage, 1), '%');
50 }
51
52 static String formatByteNumber(size_t number)
53 {
54     if (number >= 1024 * 1048576)
55         return makeString(FormattedNumber::fixedWidth(number / (1024. * 1048576), 3), " GB");
56     if (number >= 1048576)
57         return makeString(FormattedNumber::fixedWidth(number / 1048576., 2), " MB");
58     if (number >= 1024)
59         return makeString(FormattedNumber::fixedWidth(number / 1024, 1), " kB");
60     return String::number(number);
61 }
62
63 static String gcTimerString(MonotonicTime timerFireDate, MonotonicTime now)
64 {
65     if (std::isnan(timerFireDate))
66         return "[not scheduled]"_s;
67     return String::numberToStringFixedPrecision((timerFireDate - now).seconds());
68 }
69
70 static const float gFontSize = 14;
71
72 class ResourceUsageOverlayPainter final : public GraphicsLayerClient {
73 public:
74     ResourceUsageOverlayPainter(ResourceUsageOverlay& overlay)
75         : m_overlay(overlay)
76     {
77         FontCascadeDescription fontDescription;
78         RenderTheme::singleton().systemFont(CSSValueMessageBox, fontDescription);
79         fontDescription.setComputedSize(gFontSize);
80         m_textFont = FontCascade(WTFMove(fontDescription), 0, 0);
81         m_textFont.update(nullptr);
82     }
83
84     ~ResourceUsageOverlayPainter() = default;
85
86 private:
87     void paintContents(const GraphicsLayer*, GraphicsContext& context, OptionSet<GraphicsLayerPaintingPhase>, const FloatRect& clip, GraphicsLayerPaintBehavior) override
88     {
89         GraphicsContextStateSaver stateSaver(context);
90         context.fillRect(clip, Color(0.0f, 0.0f, 0.0f, 0.8f));
91         context.setFillColor(Color(0.9f, 0.9f, 0.9f, 1.f));
92
93         FloatPoint position = { 10, 20 };
94         String string =  "CPU: " + cpuUsageString(gData.cpu);
95         context.drawText(m_textFont, TextRun(string), position);
96         position.move(0, gFontSize + 2);
97
98         string = "Memory: " + formatByteNumber(gData.totalDirtySize);
99         context.drawText(m_textFont, TextRun(string), position);
100         position.move(0, gFontSize + 2);
101
102         string = "External: " + formatByteNumber(gData.totalExternalSize);
103         context.drawText(m_textFont, TextRun(string), position);
104         position.move(0, gFontSize + 2);
105
106         string = "GC Heap: " + formatByteNumber(gData.categories[MemoryCategory::GCHeap].dirtySize);
107         context.drawText(m_textFont, TextRun(string), position);
108         position.move(0, gFontSize + 2);
109
110         string = "GC owned: " + formatByteNumber(gData.categories[MemoryCategory::GCOwned].dirtySize);
111         context.drawText(m_textFont, TextRun(string), position);
112         position.move(0, gFontSize + 2);
113
114         MonotonicTime now = MonotonicTime::now();
115         string = "Eden GC: " + gcTimerString(gData.timeOfNextEdenCollection, now);
116         context.drawText(m_textFont, TextRun(string), position);
117         position.move(0, gFontSize + 2);
118
119         string = "Full GC: " + gcTimerString(gData.timeOfNextFullCollection, now);
120         context.drawText(m_textFont, TextRun(string), position);
121         position.move(0, gFontSize + 2);
122     }
123
124     void notifyFlushRequired(const GraphicsLayer*) override
125     {
126         m_overlay.overlay().page()->chrome().client().scheduleCompositingLayerFlush();
127     }
128
129     ResourceUsageOverlay& m_overlay;
130     FontCascade m_textFont;
131 };
132
133 void ResourceUsageOverlay::platformInitialize()
134 {
135     m_overlayPainter = std::make_unique<ResourceUsageOverlayPainter>(*this);
136     m_paintLayer = GraphicsLayer::create(overlay().page()->chrome().client().graphicsLayerFactory(), *m_overlayPainter);
137     m_paintLayer->setAnchorPoint(FloatPoint3D());
138     m_paintLayer->setSize({ normalWidth, normalHeight });
139     m_paintLayer->setBackgroundColor(Color(0.0f, 0.0f, 0.0f, 0.8f));
140     m_paintLayer->setDrawsContent(true);
141     overlay().layer().addChild(*m_paintLayer);
142
143     ResourceUsageThread::addObserver(this, All, [this] (const ResourceUsageData& data) {
144         gData = data;
145         m_paintLayer->setNeedsDisplay();
146     });
147 }
148
149 void ResourceUsageOverlay::platformDestroy()
150 {
151     ResourceUsageThread::removeObserver(this);
152     if (!m_paintLayer)
153         return;
154
155     m_paintLayer->removeFromParent();
156     m_paintLayer = nullptr;
157     m_overlayPainter = nullptr;
158 }
159
160 } // namespace WebCore
161
162 #endif // ENABLE(RESOURCE_USAGE) && OS(LINUX)