Title: [107426] trunk/Source/WebKit
Revision
107426
Author
[email protected]
Date
2012-02-10 12:11:47 -0800 (Fri, 10 Feb 2012)

Log Message

[BlackBerry] Upstream graphics helper classes in WebKitSupport
https://bugs.webkit.org/show_bug.cgi?id=78278

Reviewed by Antonio Gomes.

Initial upstream, no new tests.

* blackberry/WebKitSupport/RenderQueue.cpp: Added.
* blackberry/WebKitSupport/RenderQueue.h: Added.

Modified Paths

Added Paths

Diff

Modified: trunk/Source/WebKit/ChangeLog (107425 => 107426)


--- trunk/Source/WebKit/ChangeLog	2012-02-10 20:07:54 UTC (rev 107425)
+++ trunk/Source/WebKit/ChangeLog	2012-02-10 20:11:47 UTC (rev 107426)
@@ -7,6 +7,18 @@
 
         Initial upstream, no new tests.
 
+        * blackberry/WebKitSupport/RenderQueue.cpp: Added.
+        * blackberry/WebKitSupport/RenderQueue.h: Added.
+
+2012-02-10  Rob Buis  <[email protected]>
+
+        [BlackBerry] Upstream graphics helper classes in WebKitSupport
+        https://bugs.webkit.org/show_bug.cgi?id=78278
+
+        Reviewed by Antonio Gomes.
+
+        Initial upstream, no new tests.
+
         * blackberry/WebKitSupport/SurfacePool.cpp: Added.
         * blackberry/WebKitSupport/SurfacePool.h: Added.
         * blackberry/WebKitSupport/TileIndex.h: Added.

Added: trunk/Source/WebKit/blackberry/WebKitSupport/RenderQueue.cpp (0 => 107426)


--- trunk/Source/WebKit/blackberry/WebKitSupport/RenderQueue.cpp	                        (rev 0)
+++ trunk/Source/WebKit/blackberry/WebKitSupport/RenderQueue.cpp	2012-02-10 20:11:47 UTC (rev 107426)
@@ -0,0 +1,910 @@
+/*
+ * Copyright (C) 2009, 2010, 2011, 2012 Research In Motion Limited. All rights reserved.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+ */
+
+#include "config.h"
+#include "RenderQueue.h"
+
+#include "BackingStore_p.h"
+#include "WebPageClient.h"
+#include "WebPage_p.h"
+
+#define DEBUG_RENDER_QUEUE 0
+#define DEBUG_RENDER_QUEUE_SORT 0
+
+#if DEBUG_RENDER_QUEUE
+#include <BlackBerryPlatformLog.h>
+#include <wtf/CurrentTime.h>
+#endif
+
+namespace BlackBerry {
+namespace WebKit {
+
+template<SortDirection sortDirection>
+static inline int compareRectOneDirection(const Platform::IntRect& r1, const Platform::IntRect& r2)
+{
+    switch (sortDirection) {
+    case LeftToRight:
+        return r1.x() - r2.x();
+    case RightToLeft:
+        return r2.x() - r1.x();
+    case TopToBottom:
+        return r1.y() - r2.y();
+    case BottomToTop:
+        return r2.y() - r1.y();
+    default:
+        break;
+    }
+    ASSERT_NOT_REACHED();
+    return 0;
+}
+
+template<SortDirection primarySortDirection, SortDirection secondarySortDirection>
+static bool rectIsLessThan(const Platform::IntRect& r1, const Platform::IntRect& r2)
+{
+    int primaryResult = compareRectOneDirection<primarySortDirection>(r1, r2);
+    if (primaryResult || secondarySortDirection == primarySortDirection)
+        return primaryResult < 0;
+    return compareRectOneDirection<secondarySortDirection>(r1, r2) < 0;
+}
+
+typedef bool (*FuncRectLessThan)(const Platform::IntRect& r1, const Platform::IntRect& r2);
+static FuncRectLessThan rectLessThanFunction(SortDirection primary, SortDirection secondary)
+{
+    static FuncRectLessThan s_rectLessThanFunctions[NumSortDirections][NumSortDirections] = { { 0 } };
+    static bool s_initialized = false;
+    if (!s_initialized) {
+#define ADD_COMPARE_FUNCTION(_primary, _secondary) \
+        s_rectLessThanFunctions[_primary][_secondary] = rectIsLessThan<_primary, _secondary>
+
+        ADD_COMPARE_FUNCTION(LeftToRight, LeftToRight);
+        ADD_COMPARE_FUNCTION(LeftToRight, RightToLeft);
+        ADD_COMPARE_FUNCTION(LeftToRight, TopToBottom);
+        ADD_COMPARE_FUNCTION(LeftToRight, BottomToTop);
+
+        ADD_COMPARE_FUNCTION(RightToLeft, LeftToRight);
+        ADD_COMPARE_FUNCTION(RightToLeft, RightToLeft);
+        ADD_COMPARE_FUNCTION(RightToLeft, TopToBottom);
+        ADD_COMPARE_FUNCTION(RightToLeft, BottomToTop);
+
+        ADD_COMPARE_FUNCTION(TopToBottom, LeftToRight);
+        ADD_COMPARE_FUNCTION(TopToBottom, RightToLeft);
+        ADD_COMPARE_FUNCTION(TopToBottom, TopToBottom);
+        ADD_COMPARE_FUNCTION(TopToBottom, BottomToTop);
+
+        ADD_COMPARE_FUNCTION(BottomToTop, LeftToRight);
+        ADD_COMPARE_FUNCTION(BottomToTop, RightToLeft);
+        ADD_COMPARE_FUNCTION(BottomToTop, TopToBottom);
+        ADD_COMPARE_FUNCTION(BottomToTop, BottomToTop);
+#undef ADD_COMPARE_FUNCTION
+
+        s_initialized = true;
+    }
+
+    return s_rectLessThanFunctions[primary][secondary];
+}
+
+class RectLessThan {
+public:
+    RectLessThan(SortDirection primarySortDirection, SortDirection secondarySortDirection)
+        : m_rectIsLessThan(rectLessThanFunction(primarySortDirection, secondarySortDirection))
+    {
+    }
+
+    bool operator()(const Platform::IntRect& r1, const Platform::IntRect& r2)
+    {
+        return m_rectIsLessThan(r1, r2);
+    }
+
+private:
+    FuncRectLessThan m_rectIsLessThan;
+};
+
+class RenderRectLessThan {
+public:
+    RenderRectLessThan(SortDirection primarySortDirection, SortDirection secondarySortDirection)
+        : m_rectIsLessThan(rectLessThanFunction(primarySortDirection, secondarySortDirection))
+    {
+    }
+
+    bool operator()(const RenderRect& r1, const RenderRect& r2)
+    {
+        return m_rectIsLessThan(r1.subRects()[0], r2.subRects()[0]);
+    }
+
+private:
+    FuncRectLessThan m_rectIsLessThan;
+};
+
+RenderRect::RenderRect(const Platform::IntPoint& location, const Platform::IntSize& size, int splittingFactor)
+    : Platform::IntRect(location, size)
+    , m_splittingFactor(0)
+    , m_primarySortDirection(TopToBottom)
+    , m_secondarySortDirection(LeftToRight)
+{
+    initialize(splittingFactor);
+}
+
+RenderRect::RenderRect(int x, int y, int width, int height, int splittingFactor)
+    : Platform::IntRect(x, y, width, height)
+    , m_splittingFactor(0)
+    , m_primarySortDirection(TopToBottom)
+    , m_secondarySortDirection(LeftToRight)
+{
+    initialize(splittingFactor);
+}
+
+void RenderRect::initialize(int splittingFactor)
+{
+    m_subRects.push_back(*this);
+    for (int i = 0; i < splittingFactor; ++i)
+        split();
+    quickSort();
+}
+
+static void splitRectInHalfAndAddToList(const Platform::IntRect& rect, bool vertical, IntRectList& renderRectList)
+{
+    if (vertical) {
+        int width1 = static_cast<int>(ceilf(rect.width() / 2.0));
+        int width2 = static_cast<int>(floorf(rect.width() / 2.0));
+        renderRectList.push_back(Platform::IntRect(rect.x(), rect.y(), width1, rect.height()));
+        renderRectList.push_back(Platform::IntRect(rect.x() + width1, rect.y(), width2, rect.height()));
+    } else {
+        int height1 = static_cast<int>(ceilf(rect.height() / 2.0));
+        int height2 = static_cast<int>(floorf(rect.height() / 2.0));
+        renderRectList.push_back(Platform::IntRect(rect.x(), rect.y(), rect.width(), height1));
+        renderRectList.push_back(Platform::IntRect(rect.x(), rect.y() + height1, rect.width(), height2));
+    }
+}
+
+void RenderRect::split()
+{
+    ++m_splittingFactor;
+
+    bool vertical = !(m_splittingFactor % 2);
+
+    IntRectList subRects;
+    for (size_t i = 0; i < m_subRects.size(); ++i)
+        splitRectInHalfAndAddToList(m_subRects.at(i), vertical, subRects);
+    m_subRects.swap(subRects);
+}
+
+Platform::IntRect RenderRect::rectForRendering()
+{
+    ASSERT(!m_subRects.empty());
+    Platform::IntRect rect = m_subRects[0];
+    m_subRects.erase(m_subRects.begin());
+    return rect;
+}
+
+void RenderRect::updateSortDirection(SortDirection primary, SortDirection secondary)
+{
+    if (primary == m_primarySortDirection && secondary == m_secondarySortDirection)
+        return;
+
+    m_primarySortDirection = primary;
+    m_secondarySortDirection = secondary;
+
+    quickSort();
+}
+
+void RenderRect::quickSort()
+{
+    std::sort(m_subRects.begin(), m_subRects.begin(), RectLessThan(m_primarySortDirection, m_secondarySortDirection));
+}
+
+RenderQueue::RenderQueue(BackingStorePrivate* parent)
+    : m_parent(parent)
+    , m_rectsAddedToRegularRenderJobsInCurrentCycle(false)
+    , m_currentRegularRenderJobsBatchUnderPressure(false)
+    , m_primarySortDirection(TopToBottom)
+    , m_secondarySortDirection(LeftToRight)
+{
+}
+
+void RenderQueue::reset()
+{
+    m_rectsAddedToRegularRenderJobsInCurrentCycle = false;
+    m_currentRegularRenderJobsBatchUnderPressure = false;
+    m_primarySortDirection = TopToBottom;
+    m_secondarySortDirection = LeftToRight;
+    m_visibleZoomJobs.clear();
+    m_visibleScrollJobs.clear();
+    m_visibleScrollJobsCompleted.clear();
+    m_nonVisibleScrollJobs.clear();
+    m_nonVisibleScrollJobsCompleted.clear();
+    m_regularRenderJobsRegion = Platform::IntRectRegion();
+    m_currentRegularRenderJobsBatch.clear();
+    m_currentRegularRenderJobsBatchRegion = Platform::IntRectRegion();
+    m_regularRenderJobsNotRenderedRegion = Platform::IntRectRegion();
+    m_parent->stopRenderTimer();
+    ASSERT(isEmpty());
+}
+
+int RenderQueue::splittingFactor(const Platform::IntRect& rect) const
+{
+    // This method is used to split up regular render rect jobs and we want it to
+    // to be zoom invariant with respect to WebCore. In other words, if WebCore sends
+    // us a rect of viewport size to invalidate at zoom 1.0 then we split that up
+    // in the exact same way we would at zoom 2.0. The amount of content that is
+    // rendered in any one pass should stay fixed with regard to the zoom level.
+    Platform::IntRect untransformedRect = m_parent->m_webPage->d->mapFromTransformed(rect);
+    double rectArea = untransformedRect.width() * untransformedRect.height();
+    Platform::IntSize defaultMaxLayoutSize = WebPagePrivate::defaultMaxLayoutSize();
+    double maxArea = defaultMaxLayoutSize.width() * defaultMaxLayoutSize.height();
+
+    const unsigned splitFactor = 1 << 0;
+    double renderRectArea = maxArea / splitFactor;
+    return ceil(log(rectArea / renderRectArea) / log(2.0));
+}
+
+RenderRect RenderQueue::convertToRenderRect(const Platform::IntRect& rect) const
+{
+    return RenderRect(rect.location(), rect.size(), splittingFactor(rect));
+}
+
+bool RenderQueue::isEmpty(bool shouldPerformRegularRenderJobs) const
+{
+    return m_visibleZoomJobs.empty() && m_visibleScrollJobs.empty()
+        && (!shouldPerformRegularRenderJobs || m_currentRegularRenderJobsBatch.empty())
+        && (!shouldPerformRegularRenderJobs || m_regularRenderJobsRegion.isEmpty())
+        && m_nonVisibleScrollJobs.empty();
+}
+
+bool RenderQueue::hasCurrentRegularRenderJob() const
+{
+    return !m_currentRegularRenderJobsBatch.empty() || !m_regularRenderJobsRegion.isEmpty();
+}
+
+bool RenderQueue::hasCurrentVisibleZoomJob() const
+{
+    return !m_visibleZoomJobs.empty();
+}
+
+bool RenderQueue::hasCurrentVisibleScrollJob() const
+{
+    return !m_visibleScrollJobs.empty();
+}
+
+bool RenderQueue::isCurrentVisibleScrollJob(const Platform::IntRect& rect) const
+{
+    return std::find(m_visibleScrollJobs.begin(), m_visibleScrollJobs.end(), rect) != m_visibleScrollJobs.end();
+}
+
+bool RenderQueue::isCurrentVisibleScrollJobCompleted(const Platform::IntRect& rect) const
+{
+    return std::find(m_visibleScrollJobsCompleted.begin(), m_visibleScrollJobsCompleted.end(), rect) != m_visibleScrollJobsCompleted.end();
+}
+
+bool RenderQueue::isCurrentRegularRenderJob(const Platform::IntRect& rect) const
+{
+    return m_regularRenderJobsRegion.isRectInRegion(rect) == Platform::IntRectRegion::ContainedInRegion
+        || m_currentRegularRenderJobsBatchRegion.isRectInRegion(rect) == Platform::IntRectRegion::ContainedInRegion;
+}
+
+bool RenderQueue::currentRegularRenderJobBatchUnderPressure() const
+{
+    return m_currentRegularRenderJobsBatchUnderPressure;
+}
+
+void RenderQueue::setCurrentRegularRenderJobBatchUnderPressure(bool currentRegularRenderJobsBatchUnderPressure)
+{
+    m_currentRegularRenderJobsBatchUnderPressure = currentRegularRenderJobsBatchUnderPressure;
+}
+
+void RenderQueue::eventQueueCycled()
+{
+    // Called by the backing store when the event queue has cycled to allow the
+    // render queue to determine if the regular render jobs are under pressure.
+    if (m_rectsAddedToRegularRenderJobsInCurrentCycle && m_currentRegularRenderJobsBatchRegion.isEmpty())
+        m_currentRegularRenderJobsBatchUnderPressure = true;
+    m_rectsAddedToRegularRenderJobsInCurrentCycle = false;
+}
+
+void RenderQueue::addToQueue(JobType type, const IntRectList& rectList)
+{
+    for (size_t i = 0; i < rectList.size(); ++i)
+        addToQueue(type, rectList.at(i));
+}
+
+void RenderQueue::addToQueue(JobType type, const Platform::IntRect& rect)
+{
+    if (type == NonVisibleScroll && std::find(m_visibleScrollJobs.begin(), m_visibleScrollJobs.end(), rect) != m_visibleScrollJobs.end())
+        return; // |rect| is in a higher priority queue.
+
+    switch (type) {
+    case VisibleZoom:
+        addToScrollZoomQueue(convertToRenderRect(rect), &m_visibleZoomJobs);
+        return;
+    case VisibleScroll:
+        addToScrollZoomQueue(convertToRenderRect(rect), &m_visibleScrollJobs);
+        return;
+    case RegularRender:
+        {
+            // Flag that we added rects in the current event queue cycle.
+            m_rectsAddedToRegularRenderJobsInCurrentCycle = true;
+
+            // We try and detect if this newly added rect intersects or is contained in the currently running
+            // batch of render jobs. If so, then we have to start the batch over since we decompose individual
+            // rects into subrects and might have already rendered one of them. If the web page's content has
+            // changed state then this can lead to artifacts. We mark this by noting the batch is now under pressure
+            // and the backingstore will attempt to clear it at the next available opportunity.
+            Platform::IntRectRegion::IntersectionState state = m_currentRegularRenderJobsBatchRegion.isRectInRegion(rect);
+            if (state == Platform::IntRectRegion::ContainedInRegion || state == Platform::IntRectRegion::PartiallyContainedInRegion) {
+                m_regularRenderJobsRegion = Platform::IntRectRegion::unionRegions(m_regularRenderJobsRegion, m_currentRegularRenderJobsBatchRegion);
+                m_currentRegularRenderJobsBatch.clear();
+                m_currentRegularRenderJobsBatchRegion = Platform::IntRectRegion();
+                m_currentRegularRenderJobsBatchUnderPressure = true;
+            }
+            addToRegularQueue(rect);
+        }
+        return;
+    case NonVisibleScroll:
+        addToScrollZoomQueue(convertToRenderRect(rect), &m_nonVisibleScrollJobs);
+        return;
+    }
+    ASSERT_NOT_REACHED();
+}
+
+void RenderQueue::addToRegularQueue(const Platform::IntRect& rect)
+{
+#if DEBUG_RENDER_QUEUE
+    if (m_regularRenderJobsRegion.isRectInRegion(rect) != Platform::IntRectRegion::ContainedInRegion) {
+        BlackBerry::Platform::log(BlackBerry::Platform::LogLevelCritical, "RenderQueue::addToRegularQueue %d,%d %dx%d",
+                               rect.x(), rect.y(), rect.width(), rect.height());
+    }
+#endif
+
+    // Do not let the regular render queue grow past a maximum of 3 disjoint rects.
+    if (m_regularRenderJobsRegion.numRects() > 2)
+        m_regularRenderJobsRegion = Platform::unionOfRects(m_regularRenderJobsRegion.extents(), rect);
+    else
+        m_regularRenderJobsRegion = Platform::IntRectRegion::unionRegions(m_regularRenderJobsRegion, rect);
+
+    if (!isEmpty())
+        m_parent->startRenderTimer(); // Start the render timer since we could have some stale content here...
+}
+
+void RenderQueue::addToScrollZoomQueue(const RenderRect& rect, RenderRectList* rectList)
+{
+    if (std::find(rectList->begin(), rectList->end(), rect) != rectList->end())
+        return;
+
+#if DEBUG_RENDER_QUEUE
+    BlackBerry::Platform::log(BlackBerry::Platform::LogLevelCritical, "RenderQueue::addToScrollZoomQueue %d,%d %dx%d",
+                           rect.x(), rect.y(), rect.width(), rect.height());
+#endif
+    rectList->push_back(rect);
+
+    if (!isEmpty())
+        m_parent->startRenderTimer(); // Start the render timer since we know we could have some checkerboard here...
+}
+
+void RenderQueue::quickSort(RenderRectList* queue)
+{
+    size_t length = queue->size();
+    if (!length)
+        return;
+
+    for (size_t i = 0; i < length; ++i)
+        queue->at(i).updateSortDirection(m_primarySortDirection, m_secondarySortDirection);
+    return std::sort(queue->begin(), queue->end(), RenderRectLessThan(m_primarySortDirection, m_secondarySortDirection));
+}
+
+void RenderQueue::updateSortDirection(int lastDeltaX, int lastDeltaY)
+{
+    bool primaryIsHorizontal = abs(lastDeltaX) >= abs(lastDeltaY);
+    if (primaryIsHorizontal) {
+        m_primarySortDirection = lastDeltaX <= 0 ? LeftToRight : RightToLeft;
+        m_secondarySortDirection = lastDeltaY <= 0 ? TopToBottom : BottomToTop;
+    } else {
+        m_primarySortDirection = lastDeltaY <= 0 ? TopToBottom : BottomToTop;
+        m_secondarySortDirection = lastDeltaX <= 0 ? LeftToRight : RightToLeft;
+    }
+}
+
+void RenderQueue::visibleContentChanged(const Platform::IntRect& visibleContent)
+{
+    if (m_visibleScrollJobs.empty() && m_nonVisibleScrollJobs.empty()) {
+        ASSERT(m_visibleScrollJobsCompleted.empty() && m_nonVisibleScrollJobsCompleted.empty());
+        return;
+    }
+
+    // Move visibleScrollJobs to nonVisibleScrollJobs if they do not intersect
+    // the visible content rect.
+    for (size_t i = 0; i < m_visibleScrollJobs.size(); ++i) {
+        RenderRect rect = m_visibleScrollJobs.at(i);
+        if (!rect.intersects(visibleContent)) {
+            m_visibleScrollJobs.erase(m_visibleScrollJobs.begin() + i);
+            addToScrollZoomQueue(rect, &m_nonVisibleScrollJobs);
+            --i;
+        }
+    }
+
+    // Do the same for the completed list.
+    for (size_t i = 0; i < m_visibleScrollJobsCompleted.size(); ++i) {
+        RenderRect rect = m_visibleScrollJobsCompleted.at(i);
+        if (!rect.intersects(visibleContent)) {
+            m_visibleScrollJobsCompleted.erase(m_visibleScrollJobsCompleted.begin() + i);
+            addToScrollZoomQueue(rect, &m_nonVisibleScrollJobsCompleted);
+            --i;
+        }
+    }
+
+    // Move nonVisibleScrollJobs to visibleScrollJobs if they do intersect
+    // the visible content rect.
+    for (size_t i = 0; i < m_nonVisibleScrollJobs.size(); ++i) {
+        RenderRect rect = m_nonVisibleScrollJobs.at(i);
+        if (rect.intersects(visibleContent)) {
+            m_nonVisibleScrollJobs.erase(m_nonVisibleScrollJobs.begin() + i);
+            addToScrollZoomQueue(rect, &m_visibleScrollJobs);
+            --i;
+        }
+    }
+
+    // Do the same for the completed list.
+    for (size_t i = 0; i < m_nonVisibleScrollJobsCompleted.size(); ++i) {
+        RenderRect rect = m_nonVisibleScrollJobsCompleted.at(i);
+        if (rect.intersects(visibleContent)) {
+            m_nonVisibleScrollJobsCompleted.erase(m_nonVisibleScrollJobsCompleted.begin() + i);
+            addToScrollZoomQueue(rect, &m_visibleScrollJobsCompleted);
+            --i;
+        }
+    }
+
+    if (m_visibleScrollJobs.empty() && !m_visibleScrollJobsCompleted.empty())
+        visibleScrollJobsCompleted(false /*shouldBlit*/);
+
+    if (m_nonVisibleScrollJobs.empty() && !m_nonVisibleScrollJobsCompleted.empty())
+        nonVisibleScrollJobsCompleted();
+
+    // We shouldn't be empty because the early return above and the fact that this
+    // method just shuffles rects from queue to queue hence the total number of
+    // rects in the various queues should be conserved.
+    ASSERT(!isEmpty());
+}
+
+void RenderQueue::clear(const Platform::IntRectRegion& region, bool clearRegularRenderJobs)
+{
+    IntRectList rects = region.rects();
+    for (size_t i = 0; i < rects.size(); ++i)
+        clear(rects.at(i), clearRegularRenderJobs);
+}
+
+void RenderQueue::clear(const Platform::IntRect& rect, bool clearRegularRenderJobs)
+{
+    if (m_visibleScrollJobs.empty() && m_nonVisibleScrollJobs.empty())
+        ASSERT(m_visibleScrollJobsCompleted.empty() && m_nonVisibleScrollJobsCompleted.empty());
+
+    // Remove all rects from all queues that are contained by this rect.
+    for (size_t i = 0; i < m_visibleScrollJobs.size(); ++i) {
+        if (rect.contains(m_visibleScrollJobs.at(i))) {
+            m_visibleScrollJobs.erase(m_visibleScrollJobs.begin() + i);
+            --i;
+        }
+    }
+
+    for (size_t i = 0; i < m_visibleScrollJobsCompleted.size(); ++i) {
+        if (rect.contains(m_visibleScrollJobsCompleted.at(i))) {
+            m_visibleScrollJobsCompleted.erase(m_visibleScrollJobsCompleted.begin() + i);
+            --i;
+        }
+    }
+
+    for (size_t i = 0; i < m_nonVisibleScrollJobs.size(); ++i) {
+        if (rect.contains(m_nonVisibleScrollJobs.at(i))) {
+            m_nonVisibleScrollJobs.erase(m_nonVisibleScrollJobs.begin() + i);
+            --i;
+        }
+    }
+
+    for (size_t i = 0; i < m_nonVisibleScrollJobsCompleted.size(); ++i) {
+        if (rect.contains(m_nonVisibleScrollJobsCompleted.at(i))) {
+            m_nonVisibleScrollJobsCompleted.erase(m_nonVisibleScrollJobsCompleted.begin() + i);
+            --i;
+        }
+    }
+
+    // Only clear the regular render jobs if the flag has been set.
+    if (clearRegularRenderJobs)
+        this->clearRegularRenderJobs(rect);
+
+    if (m_visibleScrollJobs.empty() && !m_visibleScrollJobsCompleted.empty())
+        visibleScrollJobsCompleted(false /*shouldBlit*/);
+
+    if (m_nonVisibleScrollJobs.empty() && !m_nonVisibleScrollJobsCompleted.empty())
+        nonVisibleScrollJobsCompleted();
+
+    if (isEmpty())
+         m_parent->stopRenderTimer();
+}
+
+void RenderQueue::clearRegularRenderJobs(const Platform::IntRect& rect)
+{
+    for (size_t i = 0; i < m_currentRegularRenderJobsBatch.size(); ++i) {
+        if (rect.contains(m_currentRegularRenderJobsBatch.at(i))) {
+            m_currentRegularRenderJobsBatch.erase(m_currentRegularRenderJobsBatch.begin() + i);
+            --i;
+        }
+    }
+    m_regularRenderJobsRegion = Platform::IntRectRegion::subtractRegions(m_regularRenderJobsRegion, rect);
+    m_currentRegularRenderJobsBatchRegion = Platform::IntRectRegion::subtractRegions(m_currentRegularRenderJobsBatchRegion, rect);
+    m_regularRenderJobsNotRenderedRegion = Platform::IntRectRegion::subtractRegions(m_regularRenderJobsNotRenderedRegion, rect);
+}
+
+void RenderQueue::clearVisibleZoom()
+{
+    m_visibleZoomJobs.clear();
+    if (isEmpty())
+         m_parent->stopRenderTimer();
+}
+
+bool RenderQueue::regularRenderJobsPreviouslyAttemptedButNotRendered(const Platform::IntRect& rect)
+{
+    return m_regularRenderJobsNotRenderedRegion.isRectInRegion(rect) != Platform::IntRectRegion::NotInRegion;
+}
+
+void RenderQueue::render(bool shouldPerformRegularRenderJobs)
+{
+    // We request a layout here to ensure that we're executing jobs in the correct
+    // order. If we didn't request a layout here then the jobs below could result
+    // in a layout and that layout can alter this queue. So request layout if needed
+    // to ensure that the queues below are in constant state before performing the
+    // next rendering job.
+
+#if DEBUG_RENDER_QUEUE
+    // Start the time measurement.
+    double time = WTF::currentTime();
+#endif
+
+    m_parent->requestLayoutIfNeeded();
+
+#if DEBUG_RENDER_QUEUE
+    double elapsed = WTF::currentTime() - time;
+    if (elapsed)
+        BlackBerry::Platform::log(BlackBerry::Platform::LogLevelCritical, "RenderQueue::render layout elapsed=%f", elapsed);
+#endif
+
+    // Empty the queues in a precise order of priority.
+    if (!m_visibleZoomJobs.empty())
+        renderVisibleZoomJob();
+    else if (!m_visibleScrollJobs.empty())
+        renderVisibleScrollJob();
+    else if (shouldPerformRegularRenderJobs && (!m_currentRegularRenderJobsBatch.empty() || !m_regularRenderJobsRegion.isEmpty())) {
+        if (currentRegularRenderJobBatchUnderPressure())
+            renderAllCurrentRegularRenderJobs();
+        else
+            renderRegularRenderJob();
+    } else if (!m_nonVisibleScrollJobs.empty())
+        renderNonVisibleScrollJob();
+
+    if (isEmpty())
+        m_parent->stopRenderTimer();
+}
+
+void RenderQueue::renderAllCurrentRegularRenderJobs()
+{
+#if DEBUG_RENDER_QUEUE
+    // Start the time measurement...
+    double time = WTF::currentTime();
+#endif
+
+    // Request layout first
+    m_parent->requestLayoutIfNeeded();
+
+#if DEBUG_RENDER_QUEUE
+    double elapsed = WTF::currentTime() - time;
+    if (elapsed)
+        BlackBerry::Platform::log(BlackBerry::Platform::LogLevelCritical, "RenderQueue::renderAllCurrentRegularRenderJobs layout elapsed=%f", elapsed);
+#endif
+
+    // The state of render queue may be modified from inside requestLayoutIfNeeded.
+    // In fact, it can even be emptied entirely! Layout can trigger a call to
+    // RenderQueue::clear. See PR#101811 for instance. So we should check again here.
+    if (!hasCurrentRegularRenderJob())
+        return;
+
+    // If there is no current batch of jobs, then create one.
+    if (m_currentRegularRenderJobsBatchRegion.isEmpty()) {
+
+        // Create a current region object from our regular render region.
+        m_currentRegularRenderJobsBatchRegion = m_regularRenderJobsRegion;
+
+        // Clear this since we're about to render everything.
+        m_regularRenderJobsRegion = Platform::IntRectRegion();
+    }
+
+    Platform::IntRectRegion regionNotRendered;
+    if (m_parent->shouldSuppressNonVisibleRegularRenderJobs()) {
+        // Record any part of the region that doesn't intersect the current visible contents rect.
+        regionNotRendered = Platform::IntRectRegion::subtractRegions(m_currentRegularRenderJobsBatchRegion, m_parent->visibleContentsRect());
+        m_regularRenderJobsNotRenderedRegion = Platform::IntRectRegion::unionRegions(m_regularRenderJobsNotRenderedRegion, regionNotRendered);
+
+#if DEBUG_RENDER_QUEUE
+        if (!regionNotRendered.isEmpty())
+            BlackBerry::Platform::log(BlackBerry::Platform::LogLevelCritical, "RenderQueue::renderAllCurrentRegularRenderJobs region not completely rendered!");
+#endif
+
+        // Clip to the visible contents so we'll be faster.
+        m_currentRegularRenderJobsBatchRegion = Platform::IntRectRegion::intersectRegions(m_currentRegularRenderJobsBatchRegion, m_parent->visibleContentsRect());
+    }
+
+    bool rendered = false;
+    if (!m_currentRegularRenderJobsBatchRegion.isEmpty()) {
+        std::vector<Platform::IntRect> rectList = m_currentRegularRenderJobsBatchRegion.rects();
+        for (size_t i = 0; i < rectList.size(); ++i)
+            rendered = m_parent->render(rectList.at(i)) ? true : rendered;
+    }
+
+#if DEBUG_RENDER_QUEUE
+    // Stop the time measurement.
+    elapsed = WTF::currentTime() - time;
+    Platform::IntRect extents = m_currentRegularRenderJobsBatchRegion.extents();
+    int numberOfRects = m_currentRegularRenderJobsBatchRegion.rects().size();
+    BlackBerry::Platform::log(BlackBerry::Platform::LogLevelCritical, "RenderQueue::renderAllCurrentRegularRenderJobs extents=(%d,%d %dx%d) numberOfRects=%d elapsed=%f",
+                           extents.x(), extents.y(), extents.width(), extents.height(), numberOfRects, elapsed);
+#endif
+
+    // Clear the region and blit since this batch is now complete.
+    Platform::IntRect renderedRect = m_currentRegularRenderJobsBatchRegion.extents();
+    m_currentRegularRenderJobsBatch.clear();
+    m_currentRegularRenderJobsBatchRegion = Platform::IntRectRegion();
+    m_currentRegularRenderJobsBatchUnderPressure = false;
+
+    // Update the screen only if we're not scrolling or zooming.
+    if (rendered && !m_parent->isScrollingOrZooming()) {
+        if (!m_parent->shouldDirectRenderingToWindow())
+            m_parent->blitVisibleContents();
+        else
+            m_parent->invalidateWindow();
+        m_parent->m_webPage->client()->notifyContentRendered(renderedRect);
+    }
+
+    if (m_parent->shouldSuppressNonVisibleRegularRenderJobs() && !regionNotRendered.isEmpty())
+        m_parent->updateTilesForScrollOrNotRenderedRegion(false /*checkLoading*/);
+}
+
+void RenderQueue::startRegularRenderJobBatchIfNeeded()
+{
+    if (!m_currentRegularRenderJobsBatch.empty())
+        return;
+
+    // Decompose the current regular render job region into render rect pieces.
+    IntRectList regularRenderJobs = m_regularRenderJobsRegion.rects();
+
+    // The current batch...
+    m_currentRegularRenderJobsBatch = regularRenderJobs;
+
+    // Create a region object that will be checked when adding new rects before
+    // this batch has been completed.
+    m_currentRegularRenderJobsBatchRegion = m_regularRenderJobsRegion;
+
+    // Clear the former region since it is now part of this batch.
+    m_regularRenderJobsRegion = Platform::IntRectRegion();
+
+#if DEBUG_RENDER_QUEUE
+    BlackBerry::Platform::log(BlackBerry::Platform::LogLevelCritical, "RenderQueue::startRegularRenderJobBatchIfNeeded batch size is %d!", m_currentRegularRenderJobsBatch.size());
+#endif
+}
+
+void RenderQueue::renderVisibleZoomJob()
+{
+    ASSERT(m_visibleZoomJobs.size() > 0);
+
+#if DEBUG_RENDER_QUEUE
+    // Start the time measurement.
+    double time = WTF::currentTime();
+#endif
+
+    RenderRect* rect = &m_visibleZoomJobs[0];
+    ASSERT(!rect->isCompleted());
+    Platform::IntRect subRect = rect->rectForRendering();
+    if (rect->isCompleted())
+        m_visibleZoomJobs.erase(m_visibleZoomJobs.begin());
+
+    m_parent->render(subRect);
+
+    // Record that it has now been rendered via a different type of job...
+    clearRegularRenderJobs(subRect);
+
+#if DEBUG_RENDER_QUEUE
+    // Stop the time measurement
+    double elapsed = WTF::currentTime() - time;
+    BlackBerry::Platform::log(BlackBerry::Platform::LogLevelCritical, "RenderQueue::renderVisibleZoomJob rect=(%d,%d %dx%d) elapsed=%f",
+                           subRect.x(), subRect.y(), subRect.width(), subRect.height(), elapsed);
+#endif
+}
+
+void RenderQueue::renderVisibleScrollJob()
+{
+    ASSERT(!m_visibleScrollJobs.empty());
+
+#if DEBUG_RENDER_QUEUE || DEBUG_RENDER_QUEUE_SORT
+    // Start the time measurement.
+    double time = WTF::currentTime();
+#endif
+
+    quickSort(&m_visibleScrollJobs);
+
+#if DEBUG_RENDER_QUEUE_SORT
+    // Stop the time measurement
+    double elapsed = WTF::currentTime() - time;
+    BlackBerry::Platform::log(BlackBerry::Platform::LogLevelCritical, "RenderQueue::renderVisibleScrollJob sort elapsed=%f", elapsed);
+#endif
+
+    RenderRect rect = m_visibleScrollJobs[0];
+    m_visibleScrollJobs.erase(m_visibleScrollJobs.begin());
+
+    ASSERT(!rect.isCompleted());
+    Platform::IntRect subRect = rect.rectForRendering();
+    if (rect.isCompleted())
+        m_visibleScrollJobsCompleted.push_back(rect);
+    else
+        m_visibleScrollJobs.insert(m_visibleScrollJobs.begin(), rect);
+
+    m_parent->render(subRect);
+
+    // Record that it has now been rendered via a different type of job...
+    clearRegularRenderJobs(subRect);
+
+#if DEBUG_RENDER_QUEUE
+    // Stop the time measurement
+    double elapsed = WTF::currentTime() - time;
+    BlackBerry::Platform::log(BlackBerry::Platform::LogLevelCritical, "RenderQueue::renderVisibleScrollJob rect=(%d,%d %dx%d) elapsed=%f",
+                           subRect.x(), subRect.y(), subRect.width(), subRect.height(), elapsed);
+#endif
+
+    if (m_visibleScrollJobs.empty())
+        visibleScrollJobsCompleted(true /*shouldBlit*/);
+}
+
+void RenderQueue::renderRegularRenderJob()
+{
+#if DEBUG_RENDER_QUEUE
+    // Start the time measurement.
+    double time = WTF::currentTime();
+#endif
+
+    ASSERT(!m_currentRegularRenderJobsBatch.empty() || !m_regularRenderJobsRegion.isEmpty());
+
+    startRegularRenderJobBatchIfNeeded();
+
+    // Take the first job from the regular render job queue.
+    Platform::IntRect rect = m_currentRegularRenderJobsBatch[0];
+    m_currentRegularRenderJobsBatchRegion = Platform::IntRectRegion::subtractRegions(m_currentRegularRenderJobsBatchRegion, Platform::IntRectRegion(rect));
+    m_currentRegularRenderJobsBatch.erase(m_currentRegularRenderJobsBatch.begin());
+
+    Platform::IntRectRegion regionNotRendered;
+    if (m_parent->shouldSuppressNonVisibleRegularRenderJobs()) {
+        // Record any part of the region that doesn't intersect the current visible tiles rect.
+        regionNotRendered = Platform::IntRectRegion::subtractRegions(rect, m_parent->visibleContentsRect());
+        m_regularRenderJobsNotRenderedRegion = Platform::IntRectRegion::unionRegions(m_regularRenderJobsNotRenderedRegion, regionNotRendered);
+
+#if DEBUG_RENDER_QUEUE
+        if (!regionNotRendered.isEmpty()) {
+            BlackBerry::Platform::log(BlackBerry::Platform::LogLevelCritical, "RenderQueue::renderRegularRenderJob rect (%d,%d %dx%d) not completely rendered!",
+                                  rect.x(), rect.y(), rect.width(), rect.height());
+        }
+#endif
+
+        // Clip to the visible tiles so we'll be faster.
+        rect.intersect(m_parent->visibleContentsRect());
+    }
+
+    if (!rect.isEmpty())
+        m_parent->render(rect);
+
+#if DEBUG_RENDER_QUEUE
+    // Stop the time measurement.
+    double elapsed = WTF::currentTime() - time;
+    BlackBerry::Platform::log(BlackBerry::Platform::LogLevelCritical, "RenderQueue::renderRegularRenderJob rect=(%d,%d %dx%d) elapsed=%f",
+                           rect.x(), rect.y(), rect.width(), rect.height(), elapsed);
+#endif
+
+    if (m_currentRegularRenderJobsBatch.empty()) {
+        Platform::IntRect renderedRect = m_currentRegularRenderJobsBatchRegion.extents();
+        // Clear the region and the and blit since this batch is now complete.
+        m_currentRegularRenderJobsBatchRegion = Platform::IntRectRegion();
+        m_currentRegularRenderJobsBatchUnderPressure = false;
+        // Update the screen only if we're not scrolling or zooming.
+        if (!m_parent->isScrollingOrZooming()) {
+            if (!m_parent->shouldDirectRenderingToWindow())
+                m_parent->blitVisibleContents();
+            else
+                m_parent->invalidateWindow();
+            m_parent->m_webPage->client()->notifyContentRendered(renderedRect);
+        }
+    }
+
+    // Make sure we didn't alter state of the queues that should have been empty
+    // before this method was called.
+    ASSERT(m_visibleScrollJobs.empty());
+
+    if (m_parent->shouldSuppressNonVisibleRegularRenderJobs() && !regionNotRendered.isEmpty())
+        m_parent->updateTilesForScrollOrNotRenderedRegion(false /*checkLoading*/);
+}
+
+void RenderQueue::renderNonVisibleScrollJob()
+{
+    ASSERT(!m_nonVisibleScrollJobs.empty());
+
+#if DEBUG_RENDER_QUEUE || DEBUG_RENDER_QUEUE_SORT
+    // Start the time measurement.
+    double time = WTF::currentTime();
+#endif
+
+    quickSort(&m_nonVisibleScrollJobs);
+
+#if DEBUG_RENDER_QUEUE_SORT
+    // Stop the time measurement.
+    double elapsed = WTF::currentTime() - time;
+    BlackBerry::Platform::log(BlackBerry::Platform::LogLevelCritical, "RenderQueue::renderNonVisibleScrollJob sort elapsed=%f", elapsed);
+#endif
+
+    RenderRect rect = m_nonVisibleScrollJobs[0];
+    m_nonVisibleScrollJobs.erase(m_nonVisibleScrollJobs.begin());
+
+    ASSERT(!rect.isCompleted());
+    Platform::IntRect subRect = rect.rectForRendering();
+    if (rect.isCompleted())
+        m_nonVisibleScrollJobsCompleted.push_back(rect);
+    else
+        m_nonVisibleScrollJobs.insert(m_nonVisibleScrollJobs.begin(), rect);
+
+    m_parent->render(subRect);
+
+    // Record that it has now been rendered via a different type of job...
+    clearRegularRenderJobs(subRect);
+
+    // Make sure we didn't alter state of the queues that should have been empty
+    // before this method was called.
+    ASSERT(m_visibleScrollJobs.empty());
+
+#if DEBUG_RENDER_QUEUE
+    // Stop the time measurement.
+    double elapsed = WTF::currentTime() - time;
+    BlackBerry::Platform::log(BlackBerry::Platform::LogLevelCritical, "RenderQueue::renderNonVisibleScrollJob rect=(%d,%d %dx%d) elapsed=%f",
+                           subRect.x(), subRect.y(), subRect.width(), subRect.height(), elapsed);
+#endif
+
+    if (m_nonVisibleScrollJobs.empty())
+        nonVisibleScrollJobsCompleted();
+}
+
+void RenderQueue::visibleScrollJobsCompleted(bool shouldBlit)
+{
+    // Now blit to the screen if we are done and get rid of the completed list!
+    ASSERT(m_visibleScrollJobs.empty());
+    m_visibleScrollJobsCompleted.clear();
+    if (shouldBlit && !m_parent->isScrollingOrZooming()) {
+        if (!m_parent->shouldDirectRenderingToWindow())
+            m_parent->blitVisibleContents();
+        else
+            m_parent->invalidateWindow();
+        m_parent->m_webPage->client()->notifyContentRendered(m_parent->visibleContentsRect());
+    }
+}
+
+void RenderQueue::nonVisibleScrollJobsCompleted()
+{
+    // Get rid of the completed list!
+    ASSERT(m_nonVisibleScrollJobs.empty());
+    m_nonVisibleScrollJobsCompleted.clear();
+}
+
+} // namespace WebKit
+} // namespace BlackBerry

Added: trunk/Source/WebKit/blackberry/WebKitSupport/RenderQueue.h (0 => 107426)


--- trunk/Source/WebKit/blackberry/WebKitSupport/RenderQueue.h	                        (rev 0)
+++ trunk/Source/WebKit/blackberry/WebKitSupport/RenderQueue.h	2012-02-10 20:11:47 UTC (rev 107426)
@@ -0,0 +1,154 @@
+/*
+ * Copyright (C) 2009, 2010, 2011, 2012 Research In Motion Limited. All rights reserved.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+ */
+
+#ifndef RenderQueue_h
+#define RenderQueue_h
+
+#include <BlackBerryPlatformIntRectRegion.h>
+#include <BlackBerryPlatformPrimitives.h>
+#include <vector>
+
+namespace BlackBerry {
+namespace WebKit {
+
+class BackingStorePrivate;
+
+typedef std::vector<Platform::IntRect> IntRectList;
+
+enum SortDirection {
+    LeftToRight = 0,
+    RightToLeft,
+    TopToBottom,
+    BottomToTop,
+    NumSortDirections
+};
+
+class RenderRect : public Platform::IntRect {
+public:
+    RenderRect() { }
+    RenderRect(const Platform::IntPoint& location, const Platform::IntSize&, int splittingFactor);
+    RenderRect(int x, int y, int width, int height, int splittingFactor);
+    RenderRect(const Platform::IntRect&);
+
+    Platform::IntRect rectForRendering();
+
+    bool isCompleted() const { return !m_subRects.size(); }
+
+    const IntRectList& subRects() const { return m_subRects; }
+    void updateSortDirection(SortDirection primary, SortDirection secondary);
+
+private:
+    void initialize(int splittingFactor);
+    void split();
+    void quickSort();
+    int m_splittingFactor;
+    IntRectList m_subRects;
+    SortDirection m_primarySortDirection;
+    SortDirection m_secondarySortDirection;
+};
+
+typedef std::vector<RenderRect> RenderRectList;
+
+class RenderQueue {
+public:
+    enum JobType { VisibleZoom, VisibleScroll, RegularRender, NonVisibleScroll };
+    RenderQueue(BackingStorePrivate*);
+
+    void reset();
+    RenderRect convertToRenderRect(const Platform::IntRect&) const;
+
+    bool isEmpty(bool shouldPerformRegularRenderJobs = true) const;
+
+    bool hasCurrentRegularRenderJob() const;
+    bool hasCurrentVisibleZoomJob() const;
+    bool hasCurrentVisibleScrollJob() const;
+    bool isCurrentVisibleScrollJob(const Platform::IntRect&) const;
+    bool isCurrentVisibleScrollJobCompleted(const Platform::IntRect&) const;
+    bool isCurrentRegularRenderJob(const Platform::IntRect&) const;
+
+    bool currentRegularRenderJobBatchUnderPressure() const;
+    void setCurrentRegularRenderJobBatchUnderPressure(bool);
+
+    void eventQueueCycled();
+
+    void addToQueue(JobType, const Platform::IntRect&);
+    void addToQueue(JobType, const IntRectList&);
+
+    void updateSortDirection(int lastDeltaX, int lastDeltaY);
+    void visibleContentChanged(const Platform::IntRect&);
+    void clear(const Platform::IntRectRegion&, bool clearRegularRenderJobs);
+    void clear(const Platform::IntRect&, bool clearRegularRenderJobs);
+    void clearRegularRenderJobs(const Platform::IntRect&);
+    void clearVisibleZoom();
+    bool regularRenderJobsPreviouslyAttemptedButNotRendered(const Platform::IntRect&);
+    Platform::IntRectRegion regularRenderJobsNotRenderedRegion() const { return m_regularRenderJobsNotRenderedRegion; }
+
+    void render(bool shouldPerformRegularRenderJobs = true);
+    void renderAllCurrentRegularRenderJobs();
+
+private:
+    void startRegularRenderJobBatchIfNeeded();
+
+    // Render an item from the queue.
+    void renderVisibleZoomJob();
+    void renderVisibleScrollJob();
+    void renderRegularRenderJob();
+    void renderNonVisibleScrollJob();
+
+    // Methods to handle a completed set of scroll jobs.
+    void visibleScrollJobsCompleted(bool shouldBlit);
+    void nonVisibleScrollJobsCompleted();
+
+    // Internal method to add to the various queues.
+    void addToRegularQueue(const Platform::IntRect&);
+    void addToScrollZoomQueue(const RenderRect&, RenderRectList* queue);
+    void quickSort(RenderRectList*);
+
+    // The splitting factor for render rects.
+    int splittingFactor(const Platform::IntRect&) const;
+
+    BackingStorePrivate* m_parent;
+
+    // The highest priority queue.
+    RenderRectList m_visibleZoomJobs;
+    RenderRectList m_visibleScrollJobs;
+    RenderRectList m_visibleScrollJobsCompleted;
+    // The lowest priority queue.
+    RenderRectList m_nonVisibleScrollJobs;
+    RenderRectList m_nonVisibleScrollJobsCompleted;
+    // The regular render jobs are in the middle.
+    Platform::IntRectRegion m_regularRenderJobsRegion;
+    IntRectList m_currentRegularRenderJobsBatch;
+    Platform::IntRectRegion m_currentRegularRenderJobsBatchRegion;
+    bool m_rectsAddedToRegularRenderJobsInCurrentCycle;
+    bool m_currentRegularRenderJobsBatchUnderPressure;
+
+    // Holds the region of the page that we attempt to render, but the
+    // backingstore was not in the right place at the time. This will
+    // be checked before we try to restore a tile to it's last rendered
+    // place.
+    Platform::IntRectRegion m_regularRenderJobsNotRenderedRegion;
+
+    SortDirection m_primarySortDirection;
+    SortDirection m_secondarySortDirection;
+};
+
+} // namespace WebKit
+} // namespace BlackBerry
+
+#endif // RenderQueue_h
_______________________________________________
webkit-changes mailing list
[email protected]
http://lists.webkit.org/mailman/listinfo.cgi/webkit-changes

Reply via email to