Tile.cpp revision 8dfdf8aa25b250ed3b8c0a443cf1cbaf9bd12c5b
1a5ffb7c279df240a07658953e1bd5df6d0480cb6Nicolas Roard/*
2a5ffb7c279df240a07658953e1bd5df6d0480cb6Nicolas Roard * Copyright 2010, The Android Open Source Project
3a5ffb7c279df240a07658953e1bd5df6d0480cb6Nicolas Roard *
4a5ffb7c279df240a07658953e1bd5df6d0480cb6Nicolas Roard * Redistribution and use in source and binary forms, with or without
5a5ffb7c279df240a07658953e1bd5df6d0480cb6Nicolas Roard * modification, are permitted provided that the following conditions
6a5ffb7c279df240a07658953e1bd5df6d0480cb6Nicolas Roard * are met:
7a5ffb7c279df240a07658953e1bd5df6d0480cb6Nicolas Roard *  * Redistributions of source code must retain the above copyright
8a5ffb7c279df240a07658953e1bd5df6d0480cb6Nicolas Roard *    notice, this list of conditions and the following disclaimer.
9a5ffb7c279df240a07658953e1bd5df6d0480cb6Nicolas Roard *  * Redistributions in binary form must reproduce the above copyright
10a5ffb7c279df240a07658953e1bd5df6d0480cb6Nicolas Roard *    notice, this list of conditions and the following disclaimer in the
11a5ffb7c279df240a07658953e1bd5df6d0480cb6Nicolas Roard *    documentation and/or other materials provided with the distribution.
12a5ffb7c279df240a07658953e1bd5df6d0480cb6Nicolas Roard *
13a5ffb7c279df240a07658953e1bd5df6d0480cb6Nicolas Roard * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY
14a5ffb7c279df240a07658953e1bd5df6d0480cb6Nicolas Roard * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
15a5ffb7c279df240a07658953e1bd5df6d0480cb6Nicolas Roard * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16a5ffb7c279df240a07658953e1bd5df6d0480cb6Nicolas Roard * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR
17a5ffb7c279df240a07658953e1bd5df6d0480cb6Nicolas Roard * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
18a5ffb7c279df240a07658953e1bd5df6d0480cb6Nicolas Roard * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
19a5ffb7c279df240a07658953e1bd5df6d0480cb6Nicolas Roard * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
20a5ffb7c279df240a07658953e1bd5df6d0480cb6Nicolas Roard * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
21a5ffb7c279df240a07658953e1bd5df6d0480cb6Nicolas Roard * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22a5ffb7c279df240a07658953e1bd5df6d0480cb6Nicolas Roard * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
23a5ffb7c279df240a07658953e1bd5df6d0480cb6Nicolas Roard * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
24a5ffb7c279df240a07658953e1bd5df6d0480cb6Nicolas Roard */
25a5ffb7c279df240a07658953e1bd5df6d0480cb6Nicolas Roard
26a5ffb7c279df240a07658953e1bd5df6d0480cb6Nicolas Roard#include "config.h"
27a5ffb7c279df240a07658953e1bd5df6d0480cb6Nicolas Roard#include "BaseTile.h"
28a5ffb7c279df240a07658953e1bd5df6d0480cb6Nicolas Roard
29a5ffb7c279df240a07658953e1bd5df6d0480cb6Nicolas Roard#if USE(ACCELERATED_COMPOSITING)
30a5ffb7c279df240a07658953e1bd5df6d0480cb6Nicolas Roard
318dfdf8aa25b250ed3b8c0a443cf1cbaf9bd12c5bDerek Sollenberger#include "RasterRenderer.h"
32a5ffb7c279df240a07658953e1bd5df6d0480cb6Nicolas Roard#include "GLUtils.h"
33fca6a67b130c1f97d366460af412ec6e6de14834Derek Sollenberger#include "TextureInfo.h"
34a5ffb7c279df240a07658953e1bd5df6d0480cb6Nicolas Roard#include "TilesManager.h"
35a5ffb7c279df240a07658953e1bd5df6d0480cb6Nicolas Roard
363a7a2aa023d51b1806d4063ab0ea5ef7d488556fNicolas Roard#include <cutils/atomic.h>
37a5ffb7c279df240a07658953e1bd5df6d0480cb6Nicolas Roard
38a5ffb7c279df240a07658953e1bd5df6d0480cb6Nicolas Roard#ifdef DEBUG
39a5ffb7c279df240a07658953e1bd5df6d0480cb6Nicolas Roard
40a5ffb7c279df240a07658953e1bd5df6d0480cb6Nicolas Roard#include <cutils/log.h>
41a5ffb7c279df240a07658953e1bd5df6d0480cb6Nicolas Roard#include <wtf/CurrentTime.h>
42fca6a67b130c1f97d366460af412ec6e6de14834Derek Sollenberger#include <wtf/text/CString.h>
43a5ffb7c279df240a07658953e1bd5df6d0480cb6Nicolas Roard
44a5ffb7c279df240a07658953e1bd5df6d0480cb6Nicolas Roard#undef XLOG
45a5ffb7c279df240a07658953e1bd5df6d0480cb6Nicolas Roard#define XLOG(...) android_printLog(ANDROID_LOG_DEBUG, "BaseTile", __VA_ARGS__)
46a5ffb7c279df240a07658953e1bd5df6d0480cb6Nicolas Roard
47a5ffb7c279df240a07658953e1bd5df6d0480cb6Nicolas Roard#else
48a5ffb7c279df240a07658953e1bd5df6d0480cb6Nicolas Roard
49a5ffb7c279df240a07658953e1bd5df6d0480cb6Nicolas Roard#undef XLOG
50a5ffb7c279df240a07658953e1bd5df6d0480cb6Nicolas Roard#define XLOG(...)
51a5ffb7c279df240a07658953e1bd5df6d0480cb6Nicolas Roard
52a5ffb7c279df240a07658953e1bd5df6d0480cb6Nicolas Roard#endif // DEBUG
53a5ffb7c279df240a07658953e1bd5df6d0480cb6Nicolas Roard
54a5ffb7c279df240a07658953e1bd5df6d0480cb6Nicolas Roardnamespace WebCore {
55a5ffb7c279df240a07658953e1bd5df6d0480cb6Nicolas Roard
56ffc715a2e6382fe9e331557c35fafc426507b8f5Derek SollenbergerBaseTile::BaseTile()
57ffc715a2e6382fe9e331557c35fafc426507b8f5Derek Sollenberger    : m_page(0)
58ffc715a2e6382fe9e331557c35fafc426507b8f5Derek Sollenberger    , m_x(-1)
59ffc715a2e6382fe9e331557c35fafc426507b8f5Derek Sollenberger    , m_y(-1)
60a52793c453c1512d0a18d4ae3108a975f998ae45Derek Sollenberger    , m_texture(0)
61a5ffb7c279df240a07658953e1bd5df6d0480cb6Nicolas Roard    , m_scale(1)
62a1e806ed3b2d9e2727d08cc2a3958fce501f6f33Derek Sollenberger    , m_dirty(true)
63417789b7c56928a5fcb610583346d07ffa380900John Reck    , m_repaintPending(false)
64c9ab9bf00ba3ce8289f917675f81b40e4438a864Teng-Hui Zhu    , m_usable(true)
65a1e806ed3b2d9e2727d08cc2a3958fce501f6f33Derek Sollenberger    , m_lastDirtyPicture(0)
6667e4aa15702646d5ff50e9524f4e63eb9ed20122Nicolas Roard    , m_fullRepaintA(true)
6767e4aa15702646d5ff50e9524f4e63eb9ed20122Nicolas Roard    , m_fullRepaintB(true)
68a1e806ed3b2d9e2727d08cc2a3958fce501f6f33Derek Sollenberger    , m_lastPaintedPicture(0)
69a5ffb7c279df240a07658953e1bd5df6d0480cb6Nicolas Roard{
70a5ffb7c279df240a07658953e1bd5df6d0480cb6Nicolas Roard#ifdef DEBUG_COUNT
71da44133fe92ec11fa6b904c498e7e5cd23a43cbfNicolas Roard    ClassTracker::instance()->increment("BaseTile");
72a5ffb7c279df240a07658953e1bd5df6d0480cb6Nicolas Roard#endif
7367e4aa15702646d5ff50e9524f4e63eb9ed20122Nicolas Roard    m_currentDirtyArea = &m_dirtyAreaA;
748dfdf8aa25b250ed3b8c0a443cf1cbaf9bd12c5bDerek Sollenberger    m_renderer = new RasterRenderer();
75a5ffb7c279df240a07658953e1bd5df6d0480cb6Nicolas Roard}
76a5ffb7c279df240a07658953e1bd5df6d0480cb6Nicolas Roard
77a5ffb7c279df240a07658953e1bd5df6d0480cb6Nicolas RoardBaseTile::~BaseTile()
78a5ffb7c279df240a07658953e1bd5df6d0480cb6Nicolas Roard{
79a1e806ed3b2d9e2727d08cc2a3958fce501f6f33Derek Sollenberger    setUsedLevel(-1);
80c9ab9bf00ba3ce8289f917675f81b40e4438a864Teng-Hui Zhu    if (m_texture)
8190455eb70cca2df540942299b35bb3bd8261cb0bDerek Sollenberger        m_texture->release(this);
8290455eb70cca2df540942299b35bb3bd8261cb0bDerek Sollenberger
838dfdf8aa25b250ed3b8c0a443cf1cbaf9bd12c5bDerek Sollenberger    delete m_renderer;
848dfdf8aa25b250ed3b8c0a443cf1cbaf9bd12c5bDerek Sollenberger
85a5ffb7c279df240a07658953e1bd5df6d0480cb6Nicolas Roard#ifdef DEBUG_COUNT
86da44133fe92ec11fa6b904c498e7e5cd23a43cbfNicolas Roard    ClassTracker::instance()->decrement("BaseTile");
87a5ffb7c279df240a07658953e1bd5df6d0480cb6Nicolas Roard#endif
88a5ffb7c279df240a07658953e1bd5df6d0480cb6Nicolas Roard}
89a5ffb7c279df240a07658953e1bd5df6d0480cb6Nicolas Roard
903a7a2aa023d51b1806d4063ab0ea5ef7d488556fNicolas Roard// All the following functions must be called from the main GL thread.
913a7a2aa023d51b1806d4063ab0ea5ef7d488556fNicolas Roard
92ffc715a2e6382fe9e331557c35fafc426507b8f5Derek Sollenbergervoid BaseTile::setContents(TiledPage* page, int x, int y)
93ffc715a2e6382fe9e331557c35fafc426507b8f5Derek Sollenberger{
94ffc715a2e6382fe9e331557c35fafc426507b8f5Derek Sollenberger    android::AutoMutex lock(m_atomicSync);
95ffc715a2e6382fe9e331557c35fafc426507b8f5Derek Sollenberger    m_page = page;
96ffc715a2e6382fe9e331557c35fafc426507b8f5Derek Sollenberger    m_x = x;
97ffc715a2e6382fe9e331557c35fafc426507b8f5Derek Sollenberger    m_y = y;
98ffc715a2e6382fe9e331557c35fafc426507b8f5Derek Sollenberger}
99ffc715a2e6382fe9e331557c35fafc426507b8f5Derek Sollenberger
100a5ffb7c279df240a07658953e1bd5df6d0480cb6Nicolas Roardvoid BaseTile::reserveTexture()
101a5ffb7c279df240a07658953e1bd5df6d0480cb6Nicolas Roard{
102ec182c75fb35d955a9115fbaf516f648a48ed0e1Derek Sollenberger    BaseTileTexture* texture = TilesManager::instance()->getAvailableTexture(this);
103a1e806ed3b2d9e2727d08cc2a3958fce501f6f33Derek Sollenberger
104a1e806ed3b2d9e2727d08cc2a3958fce501f6f33Derek Sollenberger    android::AutoMutex lock(m_atomicSync);
1055ba4a087b9212ca9ae083f015637f417199d85ccJohn Reck    if (texture && m_texture != texture) {
106a1e806ed3b2d9e2727d08cc2a3958fce501f6f33Derek Sollenberger        m_lastPaintedPicture = 0;
10767e4aa15702646d5ff50e9524f4e63eb9ed20122Nicolas Roard        fullInval();
10867e4aa15702646d5ff50e9524f4e63eb9ed20122Nicolas Roard        m_texture = texture;
109a1e806ed3b2d9e2727d08cc2a3958fce501f6f33Derek Sollenberger    }
110a5ffb7c279df240a07658953e1bd5df6d0480cb6Nicolas Roard}
111a5ffb7c279df240a07658953e1bd5df6d0480cb6Nicolas Roard
112ec182c75fb35d955a9115fbaf516f648a48ed0e1Derek Sollenbergerbool BaseTile::removeTexture(BaseTileTexture* texture)
113a5ffb7c279df240a07658953e1bd5df6d0480cb6Nicolas Roard{
114245e0cdd9ea80915059080a2bedbb9ebb5cc646cNicolas Roard    XLOG("%x removeTexture res: %x... page %x", this, m_texture, m_page);
1153a7a2aa023d51b1806d4063ab0ea5ef7d488556fNicolas Roard    // We update atomically, so paintBitmap() can see the correct value
116a1e806ed3b2d9e2727d08cc2a3958fce501f6f33Derek Sollenberger    android::AutoMutex lock(m_atomicSync);
117fed0f3819356e8f1bdb6fd97c0265e2bfff1dacbNicolas Roard    if (m_texture == texture)
118fed0f3819356e8f1bdb6fd97c0265e2bfff1dacbNicolas Roard        m_texture = 0;
11981ec1fafcb2c1bc433ec34b6ae4ea78d1ea7d3a8Nicolas Roard    return true;
1203a7a2aa023d51b1806d4063ab0ea5ef7d488556fNicolas Roard}
1213a7a2aa023d51b1806d4063ab0ea5ef7d488556fNicolas Roard
12267e4aa15702646d5ff50e9524f4e63eb9ed20122Nicolas Roardvoid BaseTile::fullInval()
12367e4aa15702646d5ff50e9524f4e63eb9ed20122Nicolas Roard{
12467e4aa15702646d5ff50e9524f4e63eb9ed20122Nicolas Roard    m_dirtyAreaA.setEmpty();
12567e4aa15702646d5ff50e9524f4e63eb9ed20122Nicolas Roard    m_dirtyAreaB.setEmpty();
12667e4aa15702646d5ff50e9524f4e63eb9ed20122Nicolas Roard    m_fullRepaintA = true;
12767e4aa15702646d5ff50e9524f4e63eb9ed20122Nicolas Roard    m_fullRepaintB = true;
12867e4aa15702646d5ff50e9524f4e63eb9ed20122Nicolas Roard    m_dirty = true;
12967e4aa15702646d5ff50e9524f4e63eb9ed20122Nicolas Roard}
13067e4aa15702646d5ff50e9524f4e63eb9ed20122Nicolas Roard
1313a7a2aa023d51b1806d4063ab0ea5ef7d488556fNicolas Roardvoid BaseTile::setScale(float scale)
1323a7a2aa023d51b1806d4063ab0ea5ef7d488556fNicolas Roard{
133a1e806ed3b2d9e2727d08cc2a3958fce501f6f33Derek Sollenberger    android::AutoMutex lock(m_atomicSync);
13467e4aa15702646d5ff50e9524f4e63eb9ed20122Nicolas Roard    if (m_scale != scale) {
13567e4aa15702646d5ff50e9524f4e63eb9ed20122Nicolas Roard        m_scale = scale;
13667e4aa15702646d5ff50e9524f4e63eb9ed20122Nicolas Roard        fullInval();
13767e4aa15702646d5ff50e9524f4e63eb9ed20122Nicolas Roard    }
138a1e806ed3b2d9e2727d08cc2a3958fce501f6f33Derek Sollenberger}
139a1e806ed3b2d9e2727d08cc2a3958fce501f6f33Derek Sollenberger
14067e4aa15702646d5ff50e9524f4e63eb9ed20122Nicolas Roardvoid BaseTile::markAsDirty(int unsigned pictureCount,
14167e4aa15702646d5ff50e9524f4e63eb9ed20122Nicolas Roard                           const SkRegion& dirtyArea)
142a1e806ed3b2d9e2727d08cc2a3958fce501f6f33Derek Sollenberger{
143a1e806ed3b2d9e2727d08cc2a3958fce501f6f33Derek Sollenberger    android::AutoMutex lock(m_atomicSync);
144a1e806ed3b2d9e2727d08cc2a3958fce501f6f33Derek Sollenberger    m_lastDirtyPicture = pictureCount;
14567e4aa15702646d5ff50e9524f4e63eb9ed20122Nicolas Roard    m_dirtyAreaA.op(dirtyArea, SkRegion::kUnion_Op);
14667e4aa15702646d5ff50e9524f4e63eb9ed20122Nicolas Roard    m_dirtyAreaB.op(dirtyArea, SkRegion::kUnion_Op);
14767e4aa15702646d5ff50e9524f4e63eb9ed20122Nicolas Roard    m_dirty = true;
148a1e806ed3b2d9e2727d08cc2a3958fce501f6f33Derek Sollenberger}
149a1e806ed3b2d9e2727d08cc2a3958fce501f6f33Derek Sollenberger
150c9ab9bf00ba3ce8289f917675f81b40e4438a864Teng-Hui Zhuvoid BaseTile::setUsable(bool usable)
151c9ab9bf00ba3ce8289f917675f81b40e4438a864Teng-Hui Zhu{
152c9ab9bf00ba3ce8289f917675f81b40e4438a864Teng-Hui Zhu    android::AutoMutex lock(m_atomicSync);
153c9ab9bf00ba3ce8289f917675f81b40e4438a864Teng-Hui Zhu    m_usable = usable;
154c9ab9bf00ba3ce8289f917675f81b40e4438a864Teng-Hui Zhu}
155c9ab9bf00ba3ce8289f917675f81b40e4438a864Teng-Hui Zhu
156c9ab9bf00ba3ce8289f917675f81b40e4438a864Teng-Hui Zhu
157a1e806ed3b2d9e2727d08cc2a3958fce501f6f33Derek Sollenbergerbool BaseTile::isDirty()
158a1e806ed3b2d9e2727d08cc2a3958fce501f6f33Derek Sollenberger{
159a1e806ed3b2d9e2727d08cc2a3958fce501f6f33Derek Sollenberger    android::AutoMutex lock(m_atomicSync);
160a1e806ed3b2d9e2727d08cc2a3958fce501f6f33Derek Sollenberger    return m_dirty;
161a5ffb7c279df240a07658953e1bd5df6d0480cb6Nicolas Roard}
162a5ffb7c279df240a07658953e1bd5df6d0480cb6Nicolas Roard
163417789b7c56928a5fcb610583346d07ffa380900John Reckbool BaseTile::isRepaintPending()
164417789b7c56928a5fcb610583346d07ffa380900John Reck{
165417789b7c56928a5fcb610583346d07ffa380900John Reck    android::AutoMutex lock(m_atomicSync);
166417789b7c56928a5fcb610583346d07ffa380900John Reck    return m_repaintPending;
167417789b7c56928a5fcb610583346d07ffa380900John Reck}
168417789b7c56928a5fcb610583346d07ffa380900John Reck
169417789b7c56928a5fcb610583346d07ffa380900John Reckvoid BaseTile::setRepaintPending(bool pending)
170417789b7c56928a5fcb610583346d07ffa380900John Reck{
171417789b7c56928a5fcb610583346d07ffa380900John Reck    android::AutoMutex lock(m_atomicSync);
172417789b7c56928a5fcb610583346d07ffa380900John Reck    m_repaintPending = pending;
173417789b7c56928a5fcb610583346d07ffa380900John Reck}
174417789b7c56928a5fcb610583346d07ffa380900John Reck
175a5ffb7c279df240a07658953e1bd5df6d0480cb6Nicolas Roardvoid BaseTile::setUsedLevel(int usedLevel)
176a5ffb7c279df240a07658953e1bd5df6d0480cb6Nicolas Roard{
177a5ffb7c279df240a07658953e1bd5df6d0480cb6Nicolas Roard    if (m_texture)
178a5ffb7c279df240a07658953e1bd5df6d0480cb6Nicolas Roard        m_texture->setUsedLevel(usedLevel);
179a5ffb7c279df240a07658953e1bd5df6d0480cb6Nicolas Roard}
180a5ffb7c279df240a07658953e1bd5df6d0480cb6Nicolas Roard
181417789b7c56928a5fcb610583346d07ffa380900John Reckint BaseTile::usedLevel()
182417789b7c56928a5fcb610583346d07ffa380900John Reck{
183417789b7c56928a5fcb610583346d07ffa380900John Reck    if (m_texture)
184417789b7c56928a5fcb610583346d07ffa380900John Reck        return m_texture->usedLevel();
185417789b7c56928a5fcb610583346d07ffa380900John Reck    return -1;
186417789b7c56928a5fcb610583346d07ffa380900John Reck}
187417789b7c56928a5fcb610583346d07ffa380900John Reck
1881deed5ff76dad5d0783c0e07639338f1d6b08a67Nicolas Roardvoid BaseTile::draw(float transparency, SkRect& rect, float scale)
189a5ffb7c279df240a07658953e1bd5df6d0480cb6Nicolas Roard{
1901deed5ff76dad5d0783c0e07639338f1d6b08a67Nicolas Roard    if (m_x < 0 || m_y < 0 || m_scale != scale)
19167e4aa15702646d5ff50e9524f4e63eb9ed20122Nicolas Roard        return;
19267e4aa15702646d5ff50e9524f4e63eb9ed20122Nicolas Roard
193a1e806ed3b2d9e2727d08cc2a3958fce501f6f33Derek Sollenberger    // No need to mutex protect reads of m_texture as it is only written to by
194a1e806ed3b2d9e2727d08cc2a3958fce501f6f33Derek Sollenberger    // the consumer thread.
195a5ffb7c279df240a07658953e1bd5df6d0480cb6Nicolas Roard    if (!m_texture) {
196245e0cdd9ea80915059080a2bedbb9ebb5cc646cNicolas Roard        XLOG("%x on page %x (%d, %d) trying to draw, but no m_texture!", this, m_page, x(), y());
197a5ffb7c279df240a07658953e1bd5df6d0480cb6Nicolas Roard        return;
198a5ffb7c279df240a07658953e1bd5df6d0480cb6Nicolas Roard    }
199a5ffb7c279df240a07658953e1bd5df6d0480cb6Nicolas Roard
200c9ab9bf00ba3ce8289f917675f81b40e4438a864Teng-Hui Zhu    // Early return if set to un-usable in purpose!
2010bdd7f2d73cad03535071e5de0ba3d2f5feb1b00Teng-Hui Zhu    m_atomicSync.lock();
2020bdd7f2d73cad03535071e5de0ba3d2f5feb1b00Teng-Hui Zhu    bool usable = m_usable;
2030bdd7f2d73cad03535071e5de0ba3d2f5feb1b00Teng-Hui Zhu    bool isTexturePainted = m_lastPaintedPicture;
2040bdd7f2d73cad03535071e5de0ba3d2f5feb1b00Teng-Hui Zhu    m_atomicSync.unlock();
20544009dc8813df9eb0815bf581740a7c365f3b515Teng-Hui Zhu    if (!usable) {
20644009dc8813df9eb0815bf581740a7c365f3b515Teng-Hui Zhu        XLOG("early return at BaseTile::draw b/c tile set to unusable !");
20744009dc8813df9eb0815bf581740a7c365f3b515Teng-Hui Zhu        return;
20844009dc8813df9eb0815bf581740a7c365f3b515Teng-Hui Zhu    }
20944009dc8813df9eb0815bf581740a7c365f3b515Teng-Hui Zhu    if (!isTexturePainted) {
21044009dc8813df9eb0815bf581740a7c365f3b515Teng-Hui Zhu        XLOG("early return at BaseTile::draw b/c tile is not painted !");
211c9ab9bf00ba3ce8289f917675f81b40e4438a864Teng-Hui Zhu        return;
212c9ab9bf00ba3ce8289f917675f81b40e4438a864Teng-Hui Zhu    }
213c9ab9bf00ba3ce8289f917675f81b40e4438a864Teng-Hui Zhu
214a52793c453c1512d0a18d4ae3108a975f998ae45Derek Sollenberger    TextureInfo* textureInfo = m_texture->consumerLock();
215a5ffb7c279df240a07658953e1bd5df6d0480cb6Nicolas Roard    if (!textureInfo) {
216a5ffb7c279df240a07658953e1bd5df6d0480cb6Nicolas Roard        XLOG("%x (%d, %d) trying to draw, but no textureInfo!", this, x(), y());
217a52793c453c1512d0a18d4ae3108a975f998ae45Derek Sollenberger        m_texture->consumerRelease();
218a5ffb7c279df240a07658953e1bd5df6d0480cb6Nicolas Roard        return;
219a5ffb7c279df240a07658953e1bd5df6d0480cb6Nicolas Roard    }
220a5ffb7c279df240a07658953e1bd5df6d0480cb6Nicolas Roard
22167e4aa15702646d5ff50e9524f4e63eb9ed20122Nicolas Roard    if (m_texture->readyFor(this)) {
222d311450d853b38d1c3c3bcd2cf0955080c059f30Teng-Hui Zhu        XLOG("draw tile %d, %d, %.2f with texture %x", x(), y(), scale, m_texture);
22367e4aa15702646d5ff50e9524f4e63eb9ed20122Nicolas Roard        TilesManager::instance()->shader()->drawQuad(rect, textureInfo->m_textureId,
22464036ff80901c6af07b1f00a3a4da3966fc166c9Teng-Hui Zhu                                                     transparency,
22564036ff80901c6af07b1f00a3a4da3966fc166c9Teng-Hui Zhu                                                     textureInfo->getTextureTarget());
22667e4aa15702646d5ff50e9524f4e63eb9ed20122Nicolas Roard    }
227a52793c453c1512d0a18d4ae3108a975f998ae45Derek Sollenberger    m_texture->consumerRelease();
228a5ffb7c279df240a07658953e1bd5df6d0480cb6Nicolas Roard}
229a5ffb7c279df240a07658953e1bd5df6d0480cb6Nicolas Roard
230a1e806ed3b2d9e2727d08cc2a3958fce501f6f33Derek Sollenbergerbool BaseTile::isTileReady()
231a5ffb7c279df240a07658953e1bd5df6d0480cb6Nicolas Roard{
232a5ffb7c279df240a07658953e1bd5df6d0480cb6Nicolas Roard    if (!m_texture)
233a5ffb7c279df240a07658953e1bd5df6d0480cb6Nicolas Roard        return false;
234a5ffb7c279df240a07658953e1bd5df6d0480cb6Nicolas Roard    if (m_texture->owner() != this)
235a5ffb7c279df240a07658953e1bd5df6d0480cb6Nicolas Roard        return false;
236a1e806ed3b2d9e2727d08cc2a3958fce501f6f33Derek Sollenberger
237a1e806ed3b2d9e2727d08cc2a3958fce501f6f33Derek Sollenberger    android::AutoMutex lock(m_atomicSync);
23867e4aa15702646d5ff50e9524f4e63eb9ed20122Nicolas Roard    if (m_dirty)
23967e4aa15702646d5ff50e9524f4e63eb9ed20122Nicolas Roard        return false;
24067e4aa15702646d5ff50e9524f4e63eb9ed20122Nicolas Roard
24167e4aa15702646d5ff50e9524f4e63eb9ed20122Nicolas Roard    m_texture->consumerLock();
24267e4aa15702646d5ff50e9524f4e63eb9ed20122Nicolas Roard    bool ready = m_texture->readyFor(this);
24367e4aa15702646d5ff50e9524f4e63eb9ed20122Nicolas Roard    m_texture->consumerRelease();
24467e4aa15702646d5ff50e9524f4e63eb9ed20122Nicolas Roard
24567e4aa15702646d5ff50e9524f4e63eb9ed20122Nicolas Roard    if (ready)
24667e4aa15702646d5ff50e9524f4e63eb9ed20122Nicolas Roard        return true;
24767e4aa15702646d5ff50e9524f4e63eb9ed20122Nicolas Roard
24867e4aa15702646d5ff50e9524f4e63eb9ed20122Nicolas Roard    m_dirty = true;
24967e4aa15702646d5ff50e9524f4e63eb9ed20122Nicolas Roard    return false;
250a5ffb7c279df240a07658953e1bd5df6d0480cb6Nicolas Roard}
251a5ffb7c279df240a07658953e1bd5df6d0480cb6Nicolas Roard
2523a7a2aa023d51b1806d4063ab0ea5ef7d488556fNicolas Roard// This is called from the texture generation thread
25375394f5ee0aac2337cdff1597b4e686e22c52833Nicolas Roardvoid BaseTile::paintBitmap()
254a5ffb7c279df240a07658953e1bd5df6d0480cb6Nicolas Roard{
2553a7a2aa023d51b1806d4063ab0ea5ef7d488556fNicolas Roard
256a1e806ed3b2d9e2727d08cc2a3958fce501f6f33Derek Sollenberger    // We acquire the values below atomically. This ensures that we are reading
257a1e806ed3b2d9e2727d08cc2a3958fce501f6f33Derek Sollenberger    // values correctly across cores. Further, once we have these values they
258a1e806ed3b2d9e2727d08cc2a3958fce501f6f33Derek Sollenberger    // can be updated by other threads without consequence.
259a1e806ed3b2d9e2727d08cc2a3958fce501f6f33Derek Sollenberger    m_atomicSync.lock();
260a1e806ed3b2d9e2727d08cc2a3958fce501f6f33Derek Sollenberger    bool dirty = m_dirty;
261ec182c75fb35d955a9115fbaf516f648a48ed0e1Derek Sollenberger    BaseTileTexture* texture = m_texture;
26267e4aa15702646d5ff50e9524f4e63eb9ed20122Nicolas Roard    SkRegion dirtyArea = *m_currentDirtyArea;
2633a7a2aa023d51b1806d4063ab0ea5ef7d488556fNicolas Roard    float scale = m_scale;
264be61abb47b98988ca94bd839a1e17c3267365dc9Nicolas Roard    const int x = m_x;
265be61abb47b98988ca94bd839a1e17c3267365dc9Nicolas Roard    const int y = m_y;
266a1e806ed3b2d9e2727d08cc2a3958fce501f6f33Derek Sollenberger    m_atomicSync.unlock();
267cf1ae53e7b2853d1148ecd784379f12dffda9d43Nicolas Roard
26867e4aa15702646d5ff50e9524f4e63eb9ed20122Nicolas Roard    if (!dirty || !texture) {
26975394f5ee0aac2337cdff1597b4e686e22c52833Nicolas Roard        return;
27067e4aa15702646d5ff50e9524f4e63eb9ed20122Nicolas Roard    }
271a5ffb7c279df240a07658953e1bd5df6d0480cb6Nicolas Roard
272a1e806ed3b2d9e2727d08cc2a3958fce501f6f33Derek Sollenberger    TiledPage* tiledPage = m_page;
273a1e806ed3b2d9e2727d08cc2a3958fce501f6f33Derek Sollenberger
2747e3773d591be20a4ddb1ef7df2709fd7655b7917Nicolas Roard    texture->producerAcquireContext();
275a52793c453c1512d0a18d4ae3108a975f998ae45Derek Sollenberger    TextureInfo* textureInfo = texture->producerLock();
276a52793c453c1512d0a18d4ae3108a975f998ae45Derek Sollenberger
277a1e806ed3b2d9e2727d08cc2a3958fce501f6f33Derek Sollenberger    // at this point we can safely check the ownership (if the texture got
278a1e806ed3b2d9e2727d08cc2a3958fce501f6f33Derek Sollenberger    // transferred to another BaseTile under us)
279a52793c453c1512d0a18d4ae3108a975f998ae45Derek Sollenberger    if (texture->owner() != this || texture->usedLevel() > 1) {
280a52793c453c1512d0a18d4ae3108a975f998ae45Derek Sollenberger        texture->producerRelease();
28175394f5ee0aac2337cdff1597b4e686e22c52833Nicolas Roard        return;
282a5ffb7c279df240a07658953e1bd5df6d0480cb6Nicolas Roard    }
283a5ffb7c279df240a07658953e1bd5df6d0480cb6Nicolas Roard
28467e4aa15702646d5ff50e9524f4e63eb9ed20122Nicolas Roard    unsigned int pictureCount = 0;
28567e4aa15702646d5ff50e9524f4e63eb9ed20122Nicolas Roard
286232d0b3572d13d9b4fb1211d9d56252a1ede3ed6Derek Sollenberger    // setup the common renderInfo fields;
287232d0b3572d13d9b4fb1211d9d56252a1ede3ed6Derek Sollenberger    TileRenderInfo renderInfo;
288232d0b3572d13d9b4fb1211d9d56252a1ede3ed6Derek Sollenberger    renderInfo.x = x;
289232d0b3572d13d9b4fb1211d9d56252a1ede3ed6Derek Sollenberger    renderInfo.y = y;
290232d0b3572d13d9b4fb1211d9d56252a1ede3ed6Derek Sollenberger    renderInfo.scale = scale;
291232d0b3572d13d9b4fb1211d9d56252a1ede3ed6Derek Sollenberger    renderInfo.tileSize = texture->getSize();
292232d0b3572d13d9b4fb1211d9d56252a1ede3ed6Derek Sollenberger    renderInfo.tiledPage = tiledPage;
293232d0b3572d13d9b4fb1211d9d56252a1ede3ed6Derek Sollenberger    renderInfo.textureInfo = textureInfo;
294232d0b3572d13d9b4fb1211d9d56252a1ede3ed6Derek Sollenberger
295232d0b3572d13d9b4fb1211d9d56252a1ede3ed6Derek Sollenberger    const float tileWidth = renderInfo.tileSize.width();
296232d0b3572d13d9b4fb1211d9d56252a1ede3ed6Derek Sollenberger    const float tileHeight = renderInfo.tileSize.height();
297232d0b3572d13d9b4fb1211d9d56252a1ede3ed6Derek Sollenberger
29867e4aa15702646d5ff50e9524f4e63eb9ed20122Nicolas Roard    SkRegion::Iterator cliperator(dirtyArea);
29967e4aa15702646d5ff50e9524f4e63eb9ed20122Nicolas Roard
30067e4aa15702646d5ff50e9524f4e63eb9ed20122Nicolas Roard    bool fullRepaint = false;
301fca6a67b130c1f97d366460af412ec6e6de14834Derek Sollenberger    // TODO: Implement the partial invalidate in Surface Texture Mode
302fca6a67b130c1f97d366460af412ec6e6de14834Derek Sollenberger    if (((m_currentDirtyArea == &m_dirtyAreaA) && m_fullRepaintA)
303fca6a67b130c1f97d366460af412ec6e6de14834Derek Sollenberger            || ((m_currentDirtyArea == &m_dirtyAreaB) && m_fullRepaintB)
304ec182c75fb35d955a9115fbaf516f648a48ed0e1Derek Sollenberger            || textureInfo->m_width != tileWidth
305ec182c75fb35d955a9115fbaf516f648a48ed0e1Derek Sollenberger            || textureInfo->m_height != tileHeight
306fca6a67b130c1f97d366460af412ec6e6de14834Derek Sollenberger            || textureInfo->getSharedTextureMode() == SurfaceTextureMode) {
30767e4aa15702646d5ff50e9524f4e63eb9ed20122Nicolas Roard        fullRepaint = true;
308fca6a67b130c1f97d366460af412ec6e6de14834Derek Sollenberger    }
30967e4aa15702646d5ff50e9524f4e63eb9ed20122Nicolas Roard
310fca6a67b130c1f97d366460af412ec6e6de14834Derek Sollenberger    if (!fullRepaint) {
31167e4aa15702646d5ff50e9524f4e63eb9ed20122Nicolas Roard        while (!cliperator.done()) {
31267e4aa15702646d5ff50e9524f4e63eb9ed20122Nicolas Roard            SkRect dirtyRect;
31367e4aa15702646d5ff50e9524f4e63eb9ed20122Nicolas Roard            dirtyRect.set(cliperator.rect());
31467e4aa15702646d5ff50e9524f4e63eb9ed20122Nicolas Roard
315bc235f4153cd55951a65bfcda6dc4b6c655d8cadTeng-Hui Zhu            // compute the rect to corresponds to pixels
316bc235f4153cd55951a65bfcda6dc4b6c655d8cadTeng-Hui Zhu            SkRect realTileRect;
317fca6a67b130c1f97d366460af412ec6e6de14834Derek Sollenberger            realTileRect.fLeft = x * tileWidth;
318fca6a67b130c1f97d366460af412ec6e6de14834Derek Sollenberger            realTileRect.fTop = y * tileHeight;
319fca6a67b130c1f97d366460af412ec6e6de14834Derek Sollenberger            realTileRect.fRight = realTileRect.fLeft + tileWidth;
320fca6a67b130c1f97d366460af412ec6e6de14834Derek Sollenberger            realTileRect.fBottom = realTileRect.fTop + tileHeight;
321bc235f4153cd55951a65bfcda6dc4b6c655d8cadTeng-Hui Zhu
322bc235f4153cd55951a65bfcda6dc4b6c655d8cadTeng-Hui Zhu            // scale the dirtyRect for intersect computation.
323bc235f4153cd55951a65bfcda6dc4b6c655d8cadTeng-Hui Zhu            SkRect realDirtyRect = SkRect::MakeWH(dirtyRect.width() * scale,
324bc235f4153cd55951a65bfcda6dc4b6c655d8cadTeng-Hui Zhu                                                  dirtyRect.height() * scale);
325bc235f4153cd55951a65bfcda6dc4b6c655d8cadTeng-Hui Zhu            realDirtyRect.offset(dirtyRect.fLeft * scale, dirtyRect.fTop * scale);
326bc235f4153cd55951a65bfcda6dc4b6c655d8cadTeng-Hui Zhu
327fca6a67b130c1f97d366460af412ec6e6de14834Derek Sollenberger            // set realTileRect to the intersection of itself and the dirty rect
328bc235f4153cd55951a65bfcda6dc4b6c655d8cadTeng-Hui Zhu            if (!realTileRect.intersect(realDirtyRect)) {
32967e4aa15702646d5ff50e9524f4e63eb9ed20122Nicolas Roard                cliperator.next();
33067e4aa15702646d5ff50e9524f4e63eb9ed20122Nicolas Roard                continue;
33167e4aa15702646d5ff50e9524f4e63eb9ed20122Nicolas Roard            }
33267e4aa15702646d5ff50e9524f4e63eb9ed20122Nicolas Roard
333fca6a67b130c1f97d366460af412ec6e6de14834Derek Sollenberger            // initialize finalRealRect to the rounded values of realTileRect
33467e4aa15702646d5ff50e9524f4e63eb9ed20122Nicolas Roard            SkIRect finalRealRect;
335fca6a67b130c1f97d366460af412ec6e6de14834Derek Sollenberger            realTileRect.roundOut(&finalRealRect);
336fca6a67b130c1f97d366460af412ec6e6de14834Derek Sollenberger
337fca6a67b130c1f97d366460af412ec6e6de14834Derek Sollenberger            // stash the int values of the current width and height
338fca6a67b130c1f97d366460af412ec6e6de14834Derek Sollenberger            const int iWidth = finalRealRect.width();
339fca6a67b130c1f97d366460af412ec6e6de14834Derek Sollenberger            const int iHeight = finalRealRect.height();
340fca6a67b130c1f97d366460af412ec6e6de14834Derek Sollenberger
341fca6a67b130c1f97d366460af412ec6e6de14834Derek Sollenberger            if (iWidth == tileWidth || iHeight == tileHeight) {
342fca6a67b130c1f97d366460af412ec6e6de14834Derek Sollenberger                fullRepaint = true;
343fca6a67b130c1f97d366460af412ec6e6de14834Derek Sollenberger                break;
344fca6a67b130c1f97d366460af412ec6e6de14834Derek Sollenberger            }
345fca6a67b130c1f97d366460af412ec6e6de14834Derek Sollenberger
346fca6a67b130c1f97d366460af412ec6e6de14834Derek Sollenberger            // translate the rect into tile space coordinates
347fca6a67b130c1f97d366460af412ec6e6de14834Derek Sollenberger            finalRealRect.fLeft = finalRealRect.fLeft % static_cast<int>(tileWidth);
348fca6a67b130c1f97d366460af412ec6e6de14834Derek Sollenberger            finalRealRect.fTop = finalRealRect.fTop % static_cast<int>(tileHeight);
349fca6a67b130c1f97d366460af412ec6e6de14834Derek Sollenberger            finalRealRect.fRight = finalRealRect.fLeft + iWidth;
350fca6a67b130c1f97d366460af412ec6e6de14834Derek Sollenberger            finalRealRect.fBottom = finalRealRect.fTop + iHeight;
35167e4aa15702646d5ff50e9524f4e63eb9ed20122Nicolas Roard
352232d0b3572d13d9b4fb1211d9d56252a1ede3ed6Derek Sollenberger            renderInfo.invalRect = &finalRealRect;
353232d0b3572d13d9b4fb1211d9d56252a1ede3ed6Derek Sollenberger            renderInfo.measurePerf = false;
35467e4aa15702646d5ff50e9524f4e63eb9ed20122Nicolas Roard
3558dfdf8aa25b250ed3b8c0a443cf1cbaf9bd12c5bDerek Sollenberger            pictureCount = m_renderer->renderTiledContent(renderInfo);
35667e4aa15702646d5ff50e9524f4e63eb9ed20122Nicolas Roard
35767e4aa15702646d5ff50e9524f4e63eb9ed20122Nicolas Roard            cliperator.next();
35867e4aa15702646d5ff50e9524f4e63eb9ed20122Nicolas Roard        }
35967e4aa15702646d5ff50e9524f4e63eb9ed20122Nicolas Roard    }
360fca6a67b130c1f97d366460af412ec6e6de14834Derek Sollenberger
361fca6a67b130c1f97d366460af412ec6e6de14834Derek Sollenberger    if (fullRepaint) {
362fca6a67b130c1f97d366460af412ec6e6de14834Derek Sollenberger        SkIRect rect;
363fca6a67b130c1f97d366460af412ec6e6de14834Derek Sollenberger        rect.set(0, 0, tileWidth, tileHeight);
364fca6a67b130c1f97d366460af412ec6e6de14834Derek Sollenberger
365232d0b3572d13d9b4fb1211d9d56252a1ede3ed6Derek Sollenberger        renderInfo.invalRect = &rect;
366232d0b3572d13d9b4fb1211d9d56252a1ede3ed6Derek Sollenberger        renderInfo.measurePerf = TilesManager::instance()->getShowVisualIndicator();
367232d0b3572d13d9b4fb1211d9d56252a1ede3ed6Derek Sollenberger
3688dfdf8aa25b250ed3b8c0a443cf1cbaf9bd12c5bDerek Sollenberger        pictureCount = m_renderer->renderTiledContent(renderInfo);
369fca6a67b130c1f97d366460af412ec6e6de14834Derek Sollenberger    }
370fca6a67b130c1f97d366460af412ec6e6de14834Derek Sollenberger
37167e4aa15702646d5ff50e9524f4e63eb9ed20122Nicolas Roard    XLOG("%x update texture %x for tile %d, %d scale %.2f (m_scale: %.2f)", this, textureInfo, x, y, scale, m_scale);
372b33016812afef21c69df5ab3d5b85eab5fef7c5cDerek Sollenberger
37367e4aa15702646d5ff50e9524f4e63eb9ed20122Nicolas Roard    m_atomicSync.lock();
37467e4aa15702646d5ff50e9524f4e63eb9ed20122Nicolas Roard    texture->setTile(textureInfo, x, y, scale, pictureCount);
37567e4aa15702646d5ff50e9524f4e63eb9ed20122Nicolas Roard    texture->producerReleaseAndSwap();
37667e4aa15702646d5ff50e9524f4e63eb9ed20122Nicolas Roard
3775ba4a087b9212ca9ae083f015637f417199d85ccJohn Reck    if (texture == m_texture) {
3785ba4a087b9212ca9ae083f015637f417199d85ccJohn Reck        m_lastPaintedPicture = pictureCount;
379a5ffb7c279df240a07658953e1bd5df6d0480cb6Nicolas Roard
3805ba4a087b9212ca9ae083f015637f417199d85ccJohn Reck        // set the fullrepaint flags
381a5ffb7c279df240a07658953e1bd5df6d0480cb6Nicolas Roard
3825ba4a087b9212ca9ae083f015637f417199d85ccJohn Reck        if ((m_currentDirtyArea == &m_dirtyAreaA) && m_fullRepaintA)
3835ba4a087b9212ca9ae083f015637f417199d85ccJohn Reck            m_fullRepaintA = false;
38467e4aa15702646d5ff50e9524f4e63eb9ed20122Nicolas Roard
3855ba4a087b9212ca9ae083f015637f417199d85ccJohn Reck        if ((m_currentDirtyArea == &m_dirtyAreaB) && m_fullRepaintB)
3865ba4a087b9212ca9ae083f015637f417199d85ccJohn Reck            m_fullRepaintB = false;
38767e4aa15702646d5ff50e9524f4e63eb9ed20122Nicolas Roard
3885ba4a087b9212ca9ae083f015637f417199d85ccJohn Reck        // The various checks to see if we are still dirty...
38967e4aa15702646d5ff50e9524f4e63eb9ed20122Nicolas Roard
3905ba4a087b9212ca9ae083f015637f417199d85ccJohn Reck        m_dirty = false;
39167e4aa15702646d5ff50e9524f4e63eb9ed20122Nicolas Roard
3925ba4a087b9212ca9ae083f015637f417199d85ccJohn Reck        if (m_scale != scale)
3935ba4a087b9212ca9ae083f015637f417199d85ccJohn Reck            m_dirty = true;
39467e4aa15702646d5ff50e9524f4e63eb9ed20122Nicolas Roard
395fca6a67b130c1f97d366460af412ec6e6de14834Derek Sollenberger        if (fullRepaint)
396fca6a67b130c1f97d366460af412ec6e6de14834Derek Sollenberger            m_currentDirtyArea->setEmpty();
397fca6a67b130c1f97d366460af412ec6e6de14834Derek Sollenberger        else
3985ba4a087b9212ca9ae083f015637f417199d85ccJohn Reck            m_currentDirtyArea->op(dirtyArea, SkRegion::kDifference_Op);
39967e4aa15702646d5ff50e9524f4e63eb9ed20122Nicolas Roard
4005ba4a087b9212ca9ae083f015637f417199d85ccJohn Reck        if (!m_currentDirtyArea->isEmpty())
4015ba4a087b9212ca9ae083f015637f417199d85ccJohn Reck            m_dirty = true;
40267e4aa15702646d5ff50e9524f4e63eb9ed20122Nicolas Roard
4035ba4a087b9212ca9ae083f015637f417199d85ccJohn Reck        // Now we can swap the dirty areas
40467e4aa15702646d5ff50e9524f4e63eb9ed20122Nicolas Roard
4055ba4a087b9212ca9ae083f015637f417199d85ccJohn Reck        m_currentDirtyArea = m_currentDirtyArea == &m_dirtyAreaA ? &m_dirtyAreaB : &m_dirtyAreaA;
40667e4aa15702646d5ff50e9524f4e63eb9ed20122Nicolas Roard
4075ba4a087b9212ca9ae083f015637f417199d85ccJohn Reck        if (!m_currentDirtyArea->isEmpty())
4085ba4a087b9212ca9ae083f015637f417199d85ccJohn Reck            m_dirty = true;
409c15781f45f0d19a925be7fd73bd10c318562db70Nicolas Roard
4105ba4a087b9212ca9ae083f015637f417199d85ccJohn Reck        if (!m_dirty)
4115ba4a087b9212ca9ae083f015637f417199d85ccJohn Reck            m_usable = true;
4125ba4a087b9212ca9ae083f015637f417199d85ccJohn Reck    }
41367e4aa15702646d5ff50e9524f4e63eb9ed20122Nicolas Roard
41467e4aa15702646d5ff50e9524f4e63eb9ed20122Nicolas Roard    m_atomicSync.unlock();
41567e4aa15702646d5ff50e9524f4e63eb9ed20122Nicolas Roard}
41667e4aa15702646d5ff50e9524f4e63eb9ed20122Nicolas Roard
417a5ffb7c279df240a07658953e1bd5df6d0480cb6Nicolas Roard} // namespace WebCore
418a5ffb7c279df240a07658953e1bd5df6d0480cb6Nicolas Roard
419a5ffb7c279df240a07658953e1bd5df6d0480cb6Nicolas Roard#endif // USE(ACCELERATED_COMPOSITING)
420