1 // Copyright 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
7 #if USE(ACCELERATED_COMPOSITING)
9 #include "CCOverdrawMetrics.h"
11 #include "CCLayerTreeHost.h"
12 #include "CCLayerTreeHostImpl.h"
13 #include "CCMathUtil.h"
14 #include "FloatQuad.h"
16 #include "TraceEvent.h"
17 #include <public/Platform.h>
18 #include <public/WebTransformationMatrix.h>
20 using WebKit::WebTransformationMatrix
;
24 CCOverdrawMetrics::CCOverdrawMetrics(bool recordMetricsForFrame
)
25 : m_recordMetricsForFrame(recordMetricsForFrame
)
27 , m_pixelsUploadedOpaque(0)
28 , m_pixelsUploadedTranslucent(0)
29 , m_tilesCulledForUpload(0)
30 , m_contentsTextureUseBytes(0)
31 , m_renderSurfaceTextureUseBytes(0)
32 , m_pixelsDrawnOpaque(0)
33 , m_pixelsDrawnTranslucent(0)
34 , m_pixelsCulledForDrawing(0)
38 static inline float wedgeProduct(const FloatPoint
& p1
, const FloatPoint
& p2
)
40 return p1
.x() * p2
.y() - p1
.y() * p2
.x();
43 // Calculates area of an arbitrary convex polygon with up to 8 points.
44 static inline float polygonArea(const FloatPoint points
[8], int numPoints
)
50 for (int i
= 0; i
< numPoints
; ++i
)
51 area
+= wedgeProduct(points
[i
], points
[(i
+1)%numPoints
]);
52 return fabs(0.5f
* area
);
55 // Takes a given quad, maps it by the given transformation, and gives the area of the resulting polygon.
56 static inline float areaOfMappedQuad(const WebTransformationMatrix
& transform
, const FloatQuad
& quad
)
58 FloatPoint clippedQuad
[8];
59 int numVerticesInClippedQuad
= 0;
60 CCMathUtil::mapClippedQuad(transform
, quad
, clippedQuad
, numVerticesInClippedQuad
);
61 return polygonArea(clippedQuad
, numVerticesInClippedQuad
);
64 void CCOverdrawMetrics::didPaint(const IntRect
& paintedRect
)
66 if (!m_recordMetricsForFrame
)
69 m_pixelsPainted
+= static_cast<float>(paintedRect
.width()) * paintedRect
.height();
72 void CCOverdrawMetrics::didCullTileForUpload()
74 if (m_recordMetricsForFrame
)
75 ++m_tilesCulledForUpload
;
78 void CCOverdrawMetrics::didUpload(const WebTransformationMatrix
& transformToTarget
, const IntRect
& uploadRect
, const IntRect
& opaqueRect
)
80 if (!m_recordMetricsForFrame
)
83 float uploadArea
= areaOfMappedQuad(transformToTarget
, FloatQuad(uploadRect
));
84 float uploadOpaqueArea
= areaOfMappedQuad(transformToTarget
, FloatQuad(intersection(opaqueRect
, uploadRect
)));
86 m_pixelsUploadedOpaque
+= uploadOpaqueArea
;
87 m_pixelsUploadedTranslucent
+= uploadArea
- uploadOpaqueArea
;
90 void CCOverdrawMetrics::didUseContentsTextureMemoryBytes(size_t contentsTextureUseBytes
)
92 if (!m_recordMetricsForFrame
)
95 m_contentsTextureUseBytes
+= contentsTextureUseBytes
;
98 void CCOverdrawMetrics::didUseRenderSurfaceTextureMemoryBytes(size_t renderSurfaceUseBytes
)
100 if (!m_recordMetricsForFrame
)
103 m_renderSurfaceTextureUseBytes
+= renderSurfaceUseBytes
;
106 void CCOverdrawMetrics::didCullForDrawing(const WebTransformationMatrix
& transformToTarget
, const IntRect
& beforeCullRect
, const IntRect
& afterCullRect
)
108 if (!m_recordMetricsForFrame
)
111 float beforeCullArea
= areaOfMappedQuad(transformToTarget
, FloatQuad(beforeCullRect
));
112 float afterCullArea
= areaOfMappedQuad(transformToTarget
, FloatQuad(afterCullRect
));
114 m_pixelsCulledForDrawing
+= beforeCullArea
- afterCullArea
;
117 void CCOverdrawMetrics::didDraw(const WebTransformationMatrix
& transformToTarget
, const IntRect
& afterCullRect
, const IntRect
& opaqueRect
)
119 if (!m_recordMetricsForFrame
)
122 float afterCullArea
= areaOfMappedQuad(transformToTarget
, FloatQuad(afterCullRect
));
123 float afterCullOpaqueArea
= areaOfMappedQuad(transformToTarget
, FloatQuad(intersection(opaqueRect
, afterCullRect
)));
125 m_pixelsDrawnOpaque
+= afterCullOpaqueArea
;
126 m_pixelsDrawnTranslucent
+= afterCullArea
- afterCullOpaqueArea
;
129 void CCOverdrawMetrics::recordMetrics(const CCLayerTreeHost
* layerTreeHost
) const
131 if (m_recordMetricsForFrame
)
132 recordMetricsInternal
<CCLayerTreeHost
>(UpdateAndCommit
, layerTreeHost
);
135 void CCOverdrawMetrics::recordMetrics(const CCLayerTreeHostImpl
* layerTreeHost
) const
137 if (m_recordMetricsForFrame
)
138 recordMetricsInternal
<CCLayerTreeHostImpl
>(DrawingToScreen
, layerTreeHost
);
141 template<typename LayerTreeHostType
>
142 void CCOverdrawMetrics::recordMetricsInternal(MetricsType metricsType
, const LayerTreeHostType
* layerTreeHost
) const
144 // This gives approximately 10x the percentage of pixels to fill the viewport once.
145 float normalization
= 1000.f
/ (layerTreeHost
->deviceViewportSize().width() * layerTreeHost
->deviceViewportSize().height());
146 // This gives approximately 100x the percentage of tiles to fill the viewport once, if all tiles were 256x256.
147 float tileNormalization
= 10000.f
/ (layerTreeHost
->deviceViewportSize().width() / 256.f
* layerTreeHost
->deviceViewportSize().height() / 256.f
);
148 // This gives approximately 10x the percentage of bytes to fill the viewport once, assuming 4 bytes per pixel.
149 float byteNormalization
= normalization
/ 4;
151 switch (metricsType
) {
152 case DrawingToScreen
:
153 WebKit::Platform::current()->histogramCustomCounts("Renderer4.pixelCountOpaque_Draw", static_cast<int>(normalization
* m_pixelsDrawnOpaque
), 100, 1000000, 50);
154 WebKit::Platform::current()->histogramCustomCounts("Renderer4.pixelCountTranslucent_Draw", static_cast<int>(normalization
* m_pixelsDrawnTranslucent
), 100, 1000000, 50);
155 WebKit::Platform::current()->histogramCustomCounts("Renderer4.pixelCountCulled_Draw", static_cast<int>(normalization
* m_pixelsCulledForDrawing
), 100, 1000000, 50);
158 TRACE_COUNTER_ID1("cc", "DrawPixelsCulled", layerTreeHost
, m_pixelsCulledForDrawing
);
159 TRACE_EVENT2("cc", "CCOverdrawMetrics", "PixelsDrawnOpaque", m_pixelsDrawnOpaque
, "PixelsDrawnTranslucent", m_pixelsDrawnTranslucent
);
162 case UpdateAndCommit
:
163 WebKit::Platform::current()->histogramCustomCounts("Renderer4.pixelCountPainted", static_cast<int>(normalization
* m_pixelsPainted
), 100, 1000000, 50);
164 WebKit::Platform::current()->histogramCustomCounts("Renderer4.pixelCountOpaque_Upload", static_cast<int>(normalization
* m_pixelsUploadedOpaque
), 100, 1000000, 50);
165 WebKit::Platform::current()->histogramCustomCounts("Renderer4.pixelCountTranslucent_Upload", static_cast<int>(normalization
* m_pixelsUploadedTranslucent
), 100, 1000000, 50);
166 WebKit::Platform::current()->histogramCustomCounts("Renderer4.tileCountCulled_Upload", static_cast<int>(tileNormalization
* m_tilesCulledForUpload
), 100, 10000000, 50);
167 WebKit::Platform::current()->histogramCustomCounts("Renderer4.renderSurfaceTextureBytes_ViewportScaled", static_cast<int>(byteNormalization
* m_renderSurfaceTextureUseBytes
), 10, 1000000, 50);
168 WebKit::Platform::current()->histogramCustomCounts("Renderer4.renderSurfaceTextureBytes_Unscaled", static_cast<int>(m_renderSurfaceTextureUseBytes
/ 1000), 1000, 100000000, 50);
169 WebKit::Platform::current()->histogramCustomCounts("Renderer4.contentsTextureBytes_ViewportScaled", static_cast<int>(byteNormalization
* m_contentsTextureUseBytes
), 10, 1000000, 50);
170 WebKit::Platform::current()->histogramCustomCounts("Renderer4.contentsTextureBytes_Unscaled", static_cast<int>(m_contentsTextureUseBytes
/ 1000), 1000, 100000000, 50);
173 TRACE_COUNTER_ID1("cc", "UploadTilesCulled", layerTreeHost
, m_tilesCulledForUpload
);
174 TRACE_EVENT2("cc", "CCOverdrawMetrics", "PixelsUploadedOpaque", m_pixelsUploadedOpaque
, "PixelsUploadedTranslucent", m_pixelsUploadedTranslucent
);
177 // This must be in a different scope than the TRACE_EVENT2 above.
178 TRACE_EVENT1("cc", "CCOverdrawPaintMetrics", "PixelsPainted", m_pixelsPainted
);
181 // This must be in a different scope than the TRACE_EVENTs above.
182 TRACE_EVENT2("cc", "CCOverdrawPaintMetrics", "ContentsTextureBytes", m_contentsTextureUseBytes
, "RenderSurfaceTextureBytes", m_renderSurfaceTextureUseBytes
);