1 /*
2 * Copyright 2010, The Android Open Source Project
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 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * 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 THE COPYRIGHT HOLDERS ``AS IS'' AND ANY
14 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
15 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
17 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
18 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
19 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
20 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
21 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
23 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
24 */
25
26 #include "config.h"
27 #include "TilesProfiler.h"
28
29 #if USE(ACCELERATED_COMPOSITING)
30
31 #include "TilesManager.h"
32 #include <wtf/CurrentTime.h>
33
34 #ifdef DEBUG
35
36 #include <cutils/log.h>
37 #include <wtf/text/CString.h>
38
39 #undef XLOG
40 #define XLOG(...) android_printLog(ANDROID_LOG_DEBUG, "TilesProfiler", __VA_ARGS__)
41
42 #else
43
44 #undef XLOG
45 #define XLOG(...)
46
47 #endif // DEBUG
48
49 // Hard limit on amount of frames (and thus memory) profiling can take
50 #define MAX_PROF_FRAMES 400
51 #define INVAL_CODE -2
52
53 namespace WebCore {
TilesProfiler()54 TilesProfiler::TilesProfiler()
55 : m_enabled(false)
56 {
57 }
58
start()59 void TilesProfiler::start()
60 {
61 m_enabled = true;
62 m_goodTiles = 0;
63 m_badTiles = 0;
64 m_records.clear();
65 m_time = currentTimeMS();
66 XLOG("initializing tileprofiling");
67 }
68
stop()69 float TilesProfiler::stop()
70 {
71 m_enabled = false;
72 XLOG("completed tile profiling, observed %d frames", m_records.size());
73 return (1.0 * m_goodTiles) / (m_goodTiles + m_badTiles);
74 }
75
clear()76 void TilesProfiler::clear()
77 {
78 XLOG("clearing tile profiling of its %d frames", m_records.size());
79 m_records.clear();
80 }
81
nextFrame(int left,int top,int right,int bottom,float scale)82 void TilesProfiler::nextFrame(int left, int top, int right, int bottom, float scale)
83 {
84 if (!m_enabled || (m_records.size() > MAX_PROF_FRAMES))
85 return;
86
87 double currentTime = currentTimeMS();
88 double timeDelta = currentTime - m_time;
89 m_time = currentTime;
90
91 #ifdef DEBUG
92 if (m_records.size() != 0) {
93 XLOG("completed tile profiling frame, observed %d tiles. %f ms since last",
94 m_records[0].size(), timeDelta);
95 }
96 #endif // DEBUG
97
98 m_records.append(WTF::Vector<TileProfileRecord>());
99
100 //first record designates viewport
101 m_records.last().append(TileProfileRecord(
102 left, top, right, bottom,
103 scale, true, (int)(timeDelta * 1000)));
104 }
105
nextTile(BaseTile & tile,float scale,bool inView)106 void TilesProfiler::nextTile(BaseTile& tile, float scale, bool inView)
107 {
108 if (!m_enabled || (m_records.size() > MAX_PROF_FRAMES) || (m_records.size() == 0))
109 return;
110
111 bool isReady = tile.isTileReady();
112 int left = tile.x() * TilesManager::tileWidth();
113 int top = tile.y() * TilesManager::tileWidth();
114 int right = left + TilesManager::tileWidth();
115 int bottom = top + TilesManager::tileWidth();
116
117 if (inView) {
118 if (isReady)
119 m_goodTiles++;
120 else
121 m_badTiles++;
122 }
123 m_records.last().append(TileProfileRecord(
124 left, top, right, bottom,
125 scale, isReady, (int)tile.drawCount()));
126 XLOG("adding tile %d %d %d %d, scale %f", left, top, right, bottom, scale);
127 }
128
nextInval(const IntRect & rect,float scale)129 void TilesProfiler::nextInval(const IntRect& rect, float scale)
130 {
131 if (!m_enabled || (m_records.size() > MAX_PROF_FRAMES) || (m_records.size() == 0))
132 return;
133
134 m_records.last().append(TileProfileRecord(
135 rect.x(), rect.y(),
136 rect.maxX(), rect.maxY(), scale, false, INVAL_CODE));
137 XLOG("adding inval region %d %d %d %d, scale %f", rect.x(), rect.y(),
138 rect.maxX(), rect.maxY(), scale);
139 }
140
141 } // namespace WebCore
142
143 #endif // USE(ACCELERATED_COMPOSITING)
144