Title: [135658] trunk/Source/WebCore
Revision
135658
Author
[email protected]
Date
2012-11-24 14:25:11 -0800 (Sat, 24 Nov 2012)

Log Message

[EFL] Refactor RenderThemeEfl::getThemePartFromCache()
https://bugs.webkit.org/show_bug.cgi?id=103186

Patch by Christophe Dumez <[email protected]> on 2012-11-24
Reviewed by Kenneth Rohde Christiansen.

Refactor getThemePartFromCache() so that a list is used
for the cache instead of a vector. The function moves
items to the head of the container which is much more
efficient with a list than a vector.

The list ordering is also slightly altered so that the
cached parts that were used last come first. Previously,
they were sorted by creation time which may cause an
item to be removed from the cache because it is older
even if is was used recently.

This patch also gets rid of some code duplication at the
end of the function.

No new tests, no behavior change.

* platform/efl/RenderThemeEfl.cpp:
(WebCore::RenderThemeEfl::ThemePartCacheEntry::create): Return
a smart pointer instead of a raw pointer.
(WebCore::RenderThemeEfl::getThemePartFromCache):
(WebCore::RenderThemeEfl::clearThemePartCache): Rename
flushThemePartCache to clearThemePartCache for clarity.
(WebCore::RenderThemeEfl::loadTheme):
(WebCore::RenderThemeEfl::RenderThemeEfl):
(WebCore::RenderThemeEfl::~RenderThemeEfl):
* platform/efl/RenderThemeEfl.h:
(ThemePartCacheEntry):
(RenderThemeEfl):

Modified Paths

Diff

Modified: trunk/Source/WebCore/ChangeLog (135657 => 135658)


--- trunk/Source/WebCore/ChangeLog	2012-11-24 20:34:40 UTC (rev 135657)
+++ trunk/Source/WebCore/ChangeLog	2012-11-24 22:25:11 UTC (rev 135658)
@@ -1,3 +1,39 @@
+2012-11-24  Christophe Dumez  <[email protected]>
+
+        [EFL] Refactor RenderThemeEfl::getThemePartFromCache()
+        https://bugs.webkit.org/show_bug.cgi?id=103186
+
+        Reviewed by Kenneth Rohde Christiansen.
+
+        Refactor getThemePartFromCache() so that a list is used
+        for the cache instead of a vector. The function moves
+        items to the head of the container which is much more
+        efficient with a list than a vector.
+
+        The list ordering is also slightly altered so that the
+        cached parts that were used last come first. Previously,
+        they were sorted by creation time which may cause an
+        item to be removed from the cache because it is older
+        even if is was used recently.
+
+        This patch also gets rid of some code duplication at the
+        end of the function.
+
+        No new tests, no behavior change.
+
+        * platform/efl/RenderThemeEfl.cpp:
+        (WebCore::RenderThemeEfl::ThemePartCacheEntry::create): Return
+        a smart pointer instead of a raw pointer.
+        (WebCore::RenderThemeEfl::getThemePartFromCache):
+        (WebCore::RenderThemeEfl::clearThemePartCache): Rename 
+        flushThemePartCache to clearThemePartCache for clarity.
+        (WebCore::RenderThemeEfl::loadTheme):
+        (WebCore::RenderThemeEfl::RenderThemeEfl):
+        (WebCore::RenderThemeEfl::~RenderThemeEfl):
+        * platform/efl/RenderThemeEfl.h:
+        (ThemePartCacheEntry):
+        (RenderThemeEfl):
+
 2012-11-24  Liam Quinn  <[email protected]>
 
         [BlackBerry] RTSP should use the same MediaDocument as HTTP videos.

Modified: trunk/Source/WebCore/platform/efl/RenderThemeEfl.cpp (135657 => 135658)


--- trunk/Source/WebCore/platform/efl/RenderThemeEfl.cpp	2012-11-24 20:34:40 UTC (rev 135657)
+++ trunk/Source/WebCore/platform/efl/RenderThemeEfl.cpp	2012-11-24 22:25:11 UTC (rev 135658)
@@ -173,21 +173,21 @@
     return elementSize.width() > maxEdjeDimension || elementSize.height() > maxEdjeDimension;
 }
 
-RenderThemeEfl::ThemePartCacheEntry* RenderThemeEfl::ThemePartCacheEntry::create(const String& themePath, FormType type, const IntSize& size)
+PassOwnPtr<RenderThemeEfl::ThemePartCacheEntry> RenderThemeEfl::ThemePartCacheEntry::create(const String& themePath, FormType type, const IntSize& size)
 {
     ASSERT(!themePath.isEmpty());
 
     if (isFormElementTooLargeToDisplay(size) || size.isEmpty()) {
         EINA_LOG_ERR("Cannot render an element of size %dx%d.", size.width(), size.height());
-        return 0;
+        return nullptr;
     }
 
-    OwnPtr<ThemePartCacheEntry*> entry = adoptPtr(new ThemePartCacheEntry);
+    OwnPtr<ThemePartCacheEntry> entry = adoptPtr(new ThemePartCacheEntry);
 
     entry->m_canvas = adoptPtr(ecore_evas_buffer_new(size.width(), size.height()));
     if (!entry->canvas()) {
         EINA_LOG_ERR("ecore_evas_buffer_new(%d, %d) failed.", size.width(), size.height());
-        return 0;
+        return nullptr;
     }
 
     // By default EFL creates buffers without alpha.
@@ -197,11 +197,11 @@
     ASSERT(entry->edje());
 
     if (!setSourceGroupForEdjeObject(entry->edje(), themePath, toEdjeGroup(type)))
-        return 0;
+        return nullptr;
 
     entry->m_surface = createSurfaceForBackingStore(entry->canvas());
     if (!entry->surface())
-        return 0;
+        return nullptr;
 
     evas_object_resize(entry->edje(), size.width(), size.height());
     evas_object_show(entry->edje());
@@ -209,7 +209,7 @@
     entry->type = type;
     entry->size = size;
 
-    return entry.leakPtr();
+    return entry.release();
 }
 
 void RenderThemeEfl::ThemePartCacheEntry::reuse(const String& themePath, FormType newType, const IntSize& newSize)
@@ -240,58 +240,54 @@
 
 RenderThemeEfl::ThemePartCacheEntry* RenderThemeEfl::getThemePartFromCache(FormType type, const IntSize& size)
 {
-    Vector<ThemePartCacheEntry*>::iterator it, end;
-    size_t lastWithRequestedSize = notFound;
+    void* data;
+    Eina_List* node;
+    Eina_List* reusableNode = 0;
 
-    it = m_partCache.begin();
-    end = m_partCache.end();
-    for (size_t i = 0; it != end; i++, it++) {
-        ThemePartCacheEntry* entry = *it;
-        ASSERT(entry);
-        if (entry->size == size) {
-            if (entry->type == type)
-                return entry;
-            lastWithRequestedSize = i;
+    // Look for the item in the cache.
+    EINA_LIST_FOREACH(m_partCache, node, data) {
+        ThemePartCacheEntry* cachedEntry = static_cast<ThemePartCacheEntry*>(data);
+        if (cachedEntry->size == size) {
+            if (cachedEntry->type == type) {
+                // Found the right item, move it to the head of the list
+                // and return it.
+                m_partCache = eina_list_promote_list(m_partCache, node);
+                return cachedEntry;
+            }
+            // We reuse in priority the last item in the list that has
+            // the requested size.
+            reusableNode = node;
         }
     }
 
-    if (m_partCache.size() < RENDER_THEME_EFL_PART_CACHE_MAX) {
-        ThemePartCacheEntry* entry = ThemePartCacheEntry::create(themePath(), type, size);
-        if (entry) // Can be '0', if creation fails. Do not store it in this case.
-            m_partCache.prepend(entry);
+    if (eina_list_count(m_partCache) < RENDER_THEME_EFL_PART_CACHE_MAX) {
+        ThemePartCacheEntry* entry = ThemePartCacheEntry::create(themePath(), type, size).leakPtr();
+        if (entry)
+            m_partCache = eina_list_prepend(m_partCache, entry);
+
         return entry;
     }
 
-    // We have a full cache now!
-    EINA_LOG_INFO("RenderTheme cache is full, reusing.");
+    // The cache is full, reuse the last item we found that had the
+    // requested size to avoid resizing. If there was none, reuse
+    // the last item of the list.
+    if (!reusableNode)
+        reusableNode = eina_list_last(m_partCache);
 
-    if (lastWithRequestedSize != notFound && lastWithRequestedSize != 1) {
-        ThemePartCacheEntry* entry = m_partCache.at(lastWithRequestedSize);
-        ASSERT(entry);
-        entry->reuse(themePath(), type);
-        m_partCache.remove(lastWithRequestedSize);
-        m_partCache.prepend(entry);
-        return entry;
-    }
+    ThemePartCacheEntry* reusedEntry = static_cast<ThemePartCacheEntry*>(eina_list_data_get(reusableNode));
+    ASSERT(reusedEntry);
+    reusedEntry->reuse(themePath(), type, size);
+    m_partCache = eina_list_promote_list(m_partCache, reusableNode);
 
-    ThemePartCacheEntry* entry = m_partCache.last();
-    ASSERT(entry);
-    entry->reuse(themePath(), type, size);
-    m_partCache.removeLast();
-    m_partCache.prepend(entry);
-    return entry;
+    return reusedEntry;
 }
 
-void RenderThemeEfl::flushThemePartCache()
+void RenderThemeEfl::clearThemePartCache()
 {
-    Vector<ThemePartCacheEntry*>::iterator it, end;
+    void* data;
+    EINA_LIST_FREE(m_partCache, data)
+        delete static_cast<ThemePartCacheEntry*>(data);
 
-    it = m_partCache.begin();
-    end = m_partCache.end();
-    for (; it != end; it++)
-        delete (*it);
-
-    m_partCache.clear();
 }
 
 void RenderThemeEfl::applyEdjeStateFromForm(Evas_Object* object, ControlStates states)
@@ -494,9 +490,9 @@
     if (!setSourceGroupForEdjeObject(o.get(), m_themePath, "webkit/base"))
         return false; // Keep current theme.
 
-    // Get rid of existing theme.
+    // Invalidate existing theme part cache.
     if (edje())
-        flushThemePartCache();
+        clearThemePartCache();
 
     // Set new loaded theme, and apply it.
     m_edje = o;
@@ -606,12 +602,13 @@
     , m_mediaPanelColor(220, 220, 195) // light tannish color.
     , m_mediaSliderColor(Color::white)
 #endif
+    , m_partCache(0)
 {
 }
 
 RenderThemeEfl::~RenderThemeEfl()
 {
-    flushThemePartCache();
+    clearThemePartCache();
 }
 
 static bool supportsFocus(ControlPart appearance)

Modified: trunk/Source/WebCore/platform/efl/RenderThemeEfl.h (135657 => 135658)


--- trunk/Source/WebCore/platform/efl/RenderThemeEfl.h	2012-11-24 20:34:40 UTC (rev 135657)
+++ trunk/Source/WebCore/platform/efl/RenderThemeEfl.h	2012-11-24 22:25:11 UTC (rev 135658)
@@ -35,6 +35,7 @@
 #endif
 #include "RenderTheme.h"
 
+#include <Eina.h>
 #include <cairo.h>
 #include <wtf/efl/RefPtrEfl.h>
 
@@ -263,7 +264,7 @@
     void applyPartDescription(Evas_Object*, struct ThemePartDesc*);
 
     struct ThemePartCacheEntry {
-        static ThemePartCacheEntry* create(const String& themePath, FormType, const IntSize&);
+        static PassOwnPtr<RenderThemeEfl::ThemePartCacheEntry> create(const String& themePath, FormType, const IntSize&);
         void reuse(const String& themePath, FormType, const IntSize& = IntSize());
 
         ALWAYS_INLINE Ecore_Evas* canvas() { return m_canvas.get(); }
@@ -282,12 +283,13 @@
 
     struct ThemePartDesc m_partDescs[FormTypeLast];
 
-    // this should be small and not so frequently used,
-    // so use a vector and do linear searches
-    Vector<ThemePartCacheEntry*> m_partCache;
+    // List of ThemePartCacheEntry* sorted so that the most recently
+    // used entries come first. We use a list for efficient moving
+    // of items within the container.
+    Eina_List* m_partCache;
 
     ThemePartCacheEntry* getThemePartFromCache(FormType, const IntSize&);
-    void flushThemePartCache();
+    void clearThemePartCache();
 };
 }
 
_______________________________________________
webkit-changes mailing list
[email protected]
http://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to