OSDN Git Service

Tile profiling backend
authorChris Craik <ccraik@google.com>
Wed, 13 Jul 2011 19:58:41 +0000 (12:58 -0700)
committerChris Craik <ccraik@google.com>
Wed, 13 Jul 2011 21:02:12 +0000 (14:02 -0700)
Added tile profiling member (TilesProfiler) to TilesManager to track rendering status of tiles.

Change-Id: Ied828c6ad2a15588965e6641edecb162bd76bc62

Source/WebCore/Android.mk
Source/WebCore/platform/graphics/android/GLWebViewState.cpp
Source/WebCore/platform/graphics/android/TiledPage.cpp
Source/WebCore/platform/graphics/android/TilesManager.h
Source/WebCore/platform/graphics/android/TilesProfiler.cpp [new file with mode: 0644]
Source/WebCore/platform/graphics/android/TilesProfiler.h [new file with mode: 0644]
Source/WebKit/android/nav/WebView.cpp

index a55c8ab..4f86ac1 100644 (file)
@@ -674,6 +674,7 @@ LOCAL_SRC_FILES := $(LOCAL_SRC_FILES) \
        platform/graphics/android/TextureInfo.cpp \
        platform/graphics/android/TexturesGenerator.cpp \
        platform/graphics/android/TilesManager.cpp \
+       platform/graphics/android/TilesProfiler.cpp \
        platform/graphics/android/TiledPage.cpp \
        platform/graphics/android/VideoLayerAndroid.cpp \
        platform/graphics/android/VideoLayerManager.cpp \
index 54176e0..199ec01 100644 (file)
@@ -499,6 +499,10 @@ bool GLWebViewState::drawGL(IntRect& rect, SkRect& viewport, IntRect* invalRect,
 {
     glFinish();
     TilesManager::instance()->registerGLWebViewState(this);
+    TilesManager::instance()->getProfiler()->nextFrame(viewport.fLeft * scale,
+                                                       viewport.fTop * scale,
+                                                       viewport.fRight * scale,
+                                                       viewport.fBottom * scale);
 
     m_baseLayerLock.lock();
     BaseLayerAndroid* baseLayer = m_currentBaseLayer;
index b532d7a..1306a1d 100644 (file)
@@ -324,7 +324,8 @@ void TiledPage::draw(float transparency, const SkIRect& tileBounds)
 
     for (int j = 0; j < m_baseTileSize; j++) {
         BaseTile& tile = m_baseTiles[j];
-        if (actualTileBounds.contains(tile.x(), tile.y())) {
+        bool tileInView = actualTileBounds.contains(tile.x(), tile.y());
+        if (tileInView) {
 
             SkRect rect;
             rect.fLeft = tile.x() * tileWidth;
@@ -334,6 +335,9 @@ void TiledPage::draw(float transparency, const SkIRect& tileBounds)
 
             tile.draw(transparency, rect, m_scale);
         }
+
+        TilesManager::instance()->getProfiler()->nextTile(tile.x(), tile.y(), tile.isTileReady(),
+                                                          tile.usedLevel(), tileInView);
     }
 }
 
index fe53666..0a2fb79 100644 (file)
@@ -35,6 +35,7 @@
 #include "ShaderProgram.h"
 #include "TexturesGenerator.h"
 #include "TiledPage.h"
+#include "TilesProfiler.h"
 #include "VideoLayerManager.h"
 #include <utils/threads.h>
 #include <wtf/HashMap.h>
@@ -130,6 +131,10 @@ public:
         return SurfaceTextureMode;
     }
 
+    TilesProfiler* getProfiler() {
+        return &profiler;
+    }
+
 private:
 
     TilesManager();
@@ -168,6 +173,8 @@ private:
     unsigned int m_drawRegistrationCount;
 
     unsigned int getGLWebViewStateDrawCount(GLWebViewState* state);
+
+    TilesProfiler profiler;
 };
 
 } // namespace WebCore
diff --git a/Source/WebCore/platform/graphics/android/TilesProfiler.cpp b/Source/WebCore/platform/graphics/android/TilesProfiler.cpp
new file mode 100644 (file)
index 0000000..5c6aaa0
--- /dev/null
@@ -0,0 +1,119 @@
+/*
+ * Copyright 2010, The Android Open Source Project
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *  * Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *  * Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "TilesProfiler.h"
+
+#if USE(ACCELERATED_COMPOSITING)
+
+#include <wtf/CurrentTime.h>
+
+#ifdef DEBUG
+
+#include <cutils/log.h>
+#include <wtf/text/CString.h>
+
+#undef XLOG
+#define XLOG(...) android_printLog(ANDROID_LOG_DEBUG, "TilesProfiler", __VA_ARGS__)
+
+#else
+
+#undef XLOG
+#define XLOG(...)
+
+#endif // DEBUG
+
+// Hard limit on amount of frames (and thus memory) profiling can take
+#define MAX_PROF_FRAMES 400
+
+namespace WebCore {
+TilesProfiler::TilesProfiler()
+    : m_enabled(false)
+{
+}
+
+void TilesProfiler::start()
+{
+    m_enabled = true;
+    m_goodTiles = 0;
+    m_badTiles = 0;
+    m_records.clear();
+    m_time = currentTimeMS();
+    XLOG("initializing tileprofiling");
+}
+
+float TilesProfiler::stop()
+{
+    m_enabled = false;
+    XLOG("completed tile profiling, observed %d frames", m_records.size());
+    return (1.0 * m_goodTiles) / (m_goodTiles + m_badTiles);
+}
+
+void TilesProfiler::clear()
+{
+    XLOG("clearing tile profiling of its %d frames", m_records.size());
+    m_records.clear();
+}
+
+void TilesProfiler::nextFrame(int l, int t, int r, int b)
+{
+    if (!m_enabled || (m_records.size() > MAX_PROF_FRAMES))
+        return;
+
+    double currentTime = currentTimeMS();
+    double timeDelta = currentTime - m_time;
+    m_time = currentTime;
+
+#ifdef DEBUG
+    if (m_records.size() != 0) {
+        XLOG("completed tile profiling frame, observed %d tiles. %f ms since last",
+             m_records[0].size(), timeDelta);
+    }
+#endif // DEBUG
+
+    m_records.append(WTF::Vector<TileProfileRecord>());
+
+    //first two records designate viewport
+    m_records.last().append(TileProfileRecord(l, t, true, (int)(timeDelta * 1000)));
+    m_records.last().append(TileProfileRecord(r, b, true, -1));
+
+}
+
+void TilesProfiler::nextTile(int x, int y, bool isReady, int level, bool inView)
+{
+    if (!m_enabled || (m_records.size() > MAX_PROF_FRAMES))
+        return;
+    if (inView) {
+        if (isReady)
+            m_goodTiles++;
+        else
+            m_badTiles++;
+    }
+    m_records.last().append(TileProfileRecord(x, y, isReady, level));
+}
+
+} // namespace WebCore
+
+#endif // USE(ACCELERATED_COMPOSITING)
diff --git a/Source/WebCore/platform/graphics/android/TilesProfiler.h b/Source/WebCore/platform/graphics/android/TilesProfiler.h
new file mode 100644 (file)
index 0000000..84f8f20
--- /dev/null
@@ -0,0 +1,80 @@
+/*
+ * Copyright 2011, The Android Open Source Project
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *  * Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *  * Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef TilesProfiler_h
+#define TilesProfiler_h
+
+#if USE(ACCELERATED_COMPOSITING)
+
+#include "Vector.h"
+
+namespace WebCore {
+
+struct TileProfileRecord {
+    TileProfileRecord(int x, int y, int isReady, int level) {
+        this->x = x;
+        this->y = y;
+        this->isReady = isReady;
+        this->level = level;
+    }
+    int x, y;
+    bool isReady;
+    int level;
+};
+
+class TilesProfiler {
+public:
+    TilesProfiler();
+
+    void start();
+    float stop();
+    void clear();
+    void nextFrame(int l, int t, int r, int b);
+    void nextTile(int x, int y, bool isReady, int level, bool inView);
+
+    int numFrames() {
+        return m_records.size();
+    };
+
+    int numTilesInFrame(int frame) {
+        return m_records[frame].size();
+    }
+
+    TileProfileRecord getTile(int frame, int tile) {
+        return m_records[frame][tile];
+    }
+
+private:
+    bool m_enabled;
+    unsigned int m_goodTiles;
+    unsigned int m_badTiles;
+    Vector<Vector<TileProfileRecord> > m_records;
+    double m_time;
+};
+
+} // namespace WebCore
+
+#endif // USE(ACCELERATED_COMPOSITING)
+#endif // TilesProfiler_h
index e0bb6b4..dae3cbe 100644 (file)
@@ -1495,6 +1495,42 @@ BaseLayerAndroid* getBaseLayer() {
     return m_baseLayer;
 }
 
+void tileProfilingStart() {
+    TilesManager::instance()->getProfiler()->start();
+}
+
+float tileProfilingStop() {
+    return TilesManager::instance()->getProfiler()->stop();
+}
+
+void tileProfilingClear() {
+    TilesManager::instance()->getProfiler()->clear();
+}
+
+int tileProfilingNumFrames() {
+    return TilesManager::instance()->getProfiler()->numFrames();
+}
+
+int tileProfilingNumTilesInFrame(int frame) {
+    return TilesManager::instance()->getProfiler()->numTilesInFrame(frame);
+}
+
+int tileProfilingGetX(int frame, int tile) {
+    return TilesManager::instance()->getProfiler()->getTile(frame, tile).x;
+}
+
+int tileProfilingGetY(int frame, int tile) {
+    return TilesManager::instance()->getProfiler()->getTile(frame, tile).y;
+}
+
+bool tileProfilingGetReady(int frame, int tile) {
+    return TilesManager::instance()->getProfiler()->getTile(frame, tile).isReady;
+}
+
+int tileProfilingGetLevel(int frame, int tile) {
+    return TilesManager::instance()->getProfiler()->getTile(frame, tile).level;
+}
+
 private: // local state for WebView
     // private to getFrameCache(); other functions operate in a different thread
     CachedRoot* m_frameCacheUI; // navigation data ready for use
@@ -2446,6 +2482,51 @@ static void nativeSetSelectionPointer(JNIEnv *env, jobject obj, jboolean set,
     GET_NATIVE_VIEW(env, obj)->setSelectionPointer(set, scale, x, y);
 }
 
+static void nativeTileProfilingStart(JNIEnv *env, jobject obj)
+{
+    GET_NATIVE_VIEW(env, obj)->tileProfilingStart();
+}
+
+static float nativeTileProfilingStop(JNIEnv *env, jobject obj)
+{
+    return GET_NATIVE_VIEW(env, obj)->tileProfilingStop();
+}
+
+static void nativeTileProfilingClear(JNIEnv *env, jobject obj)
+{
+    GET_NATIVE_VIEW(env, obj)->tileProfilingClear();
+}
+
+static int nativeTileProfilingNumFrames(JNIEnv *env, jobject obj)
+{
+    return GET_NATIVE_VIEW(env, obj)->tileProfilingNumFrames();
+}
+
+static int nativeTileProfilingNumTilesInFrame(JNIEnv *env, jobject obj, int frame)
+{
+    return GET_NATIVE_VIEW(env, obj)->tileProfilingNumTilesInFrame(frame);
+}
+
+static int nativeTileProfilingGetX(JNIEnv *env, jobject obj, int frame, int tile)
+{
+    return GET_NATIVE_VIEW(env, obj)->tileProfilingGetX(frame, tile);
+}
+
+static int nativeTileProfilingGetY(JNIEnv *env, jobject obj, int frame, int tile)
+{
+    return GET_NATIVE_VIEW(env, obj)->tileProfilingGetY(frame, tile);
+}
+
+static bool nativeTileProfilingGetReady(JNIEnv *env, jobject obj, int frame, int tile)
+{
+    return GET_NATIVE_VIEW(env, obj)->tileProfilingGetReady(frame, tile);
+}
+
+static int nativeTileProfilingGetLevel(JNIEnv *env, jobject obj, int frame, int tile)
+{
+    return GET_NATIVE_VIEW(env, obj)->tileProfilingGetLevel(frame, tile);
+}
+
 #ifdef ANDROID_DUMP_DISPLAY_TREE
 static void dumpToFile(const char text[], void* file) {
     fwrite(text, 1, strlen(text), reinterpret_cast<FILE*>(file));
@@ -2703,6 +2784,24 @@ static JNINativeMethod gJavaWebViewMethods[] = {
         (void*) nativeSetSelectionPointer },
     { "nativeShowCursorTimed", "()V",
         (void*) nativeShowCursorTimed },
+    { "nativeTileProfilingStart", "()V",
+        (void*) nativeTileProfilingStart },
+    { "nativeTileProfilingStop", "()F",
+        (void*) nativeTileProfilingStop },
+    { "nativeTileProfilingClear", "()V",
+        (void*) nativeTileProfilingClear },
+    { "nativeTileProfilingNumFrames", "()I",
+        (void*) nativeTileProfilingNumFrames },
+    { "nativeTileProfilingNumTilesInFrame", "(I)I",
+        (void*) nativeTileProfilingNumTilesInFrame },
+    { "nativeTileProfilingGetX", "(II)I",
+        (void*) nativeTileProfilingGetX },
+    { "nativeTileProfilingGetY", "(II)I",
+        (void*) nativeTileProfilingGetY },
+    { "nativeTileProfilingGetReady", "(II)Z",
+        (void*) nativeTileProfilingGetReady },
+    { "nativeTileProfilingGetLevel", "(II)I",
+        (void*) nativeTileProfilingGetLevel },
     { "nativeStartSelection", "(II)Z",
         (void*) nativeStartSelection },
     { "nativeStopGL", "()V",