Tile.cpp revision 7b4a179bde698a856bed54a680438a9db3ff0566
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
26594c6b805969c2673c84d1d1d1a3556ce376ac7aChris Craik#define LOG_TAG "Tile"
27d487c56b47c747d3e331ee1892e4c0473363afd2Chris Craik#define LOG_NDEBUG 1
28d487c56b47c747d3e331ee1892e4c0473363afd2Chris Craik
29a5ffb7c279df240a07658953e1bd5df6d0480cb6Nicolas Roard#include "config.h"
30594c6b805969c2673c84d1d1d1a3556ce376ac7aChris Craik#include "Tile.h"
31a5ffb7c279df240a07658953e1bd5df6d0480cb6Nicolas Roard
32a5ffb7c279df240a07658953e1bd5df6d0480cb6Nicolas Roard#if USE(ACCELERATED_COMPOSITING)
33a5ffb7c279df240a07658953e1bd5df6d0480cb6Nicolas Roard
34d487c56b47c747d3e331ee1892e4c0473363afd2Chris Craik#include "AndroidLog.h"
35a5ffb7c279df240a07658953e1bd5df6d0480cb6Nicolas Roard#include "GLUtils.h"
36f85cf343a02e85633e6b68c7f5db3c033b780607Teng-Hui Zhu#include "RasterRenderer.h"
37fca6a67b130c1f97d366460af412ec6e6de14834Derek Sollenberger#include "TextureInfo.h"
38594c6b805969c2673c84d1d1d1a3556ce376ac7aChris Craik#include "TileTexture.h"
39a5ffb7c279df240a07658953e1bd5df6d0480cb6Nicolas Roard#include "TilesManager.h"
40a5ffb7c279df240a07658953e1bd5df6d0480cb6Nicolas Roard
41c048426c23be795d3bf870e47429167b4157a2d6Nicolas Roard// If the dirty portion of a tile exceeds this ratio, fully repaint.
42c048426c23be795d3bf870e47429167b4157a2d6Nicolas Roard// Lower values give fewer partial repaints, thus fewer front-to-back
43c048426c23be795d3bf870e47429167b4157a2d6Nicolas Roard// texture copies (cost will vary by device). It's a tradeoff between
44c048426c23be795d3bf870e47429167b4157a2d6Nicolas Roard// the rasterization cost and the FBO texture recopy cost when using
45c048426c23be795d3bf870e47429167b4157a2d6Nicolas Roard// GPU for the transfer queue.
46c048426c23be795d3bf870e47429167b4157a2d6Nicolas Roard#define MAX_INVAL_AREA 0.6
47c048426c23be795d3bf870e47429167b4157a2d6Nicolas Roard
48a5ffb7c279df240a07658953e1bd5df6d0480cb6Nicolas Roardnamespace WebCore {
49a5ffb7c279df240a07658953e1bd5df6d0480cb6Nicolas Roard
50594c6b805969c2673c84d1d1d1a3556ce376ac7aChris CraikTile::Tile(bool isLayerTile)
51885e650b12d781be054b31ae6221925a0184dc33Chris Craik    : m_x(-1)
52ffc715a2e6382fe9e331557c35fafc426507b8f5Derek Sollenberger    , m_y(-1)
538ad3ab0e47f0d5039e89c1873c178f538ec1b0dfChris Craik    , m_frontTexture(0)
548ad3ab0e47f0d5039e89c1873c178f538ec1b0dfChris Craik    , m_backTexture(0)
55a5ffb7c279df240a07658953e1bd5df6d0480cb6Nicolas Roard    , m_scale(1)
56a1e806ed3b2d9e2727d08cc2a3958fce501f6f33Derek Sollenberger    , m_dirty(true)
57417789b7c56928a5fcb610583346d07ffa380900John Reck    , m_repaintPending(false)
5862ee9670dd9beeb9a8f21d8737250c081382e2f5Teng-Hui Zhu    , m_fullRepaint(true)
593c131605fca8e29a88fdc4923d86bdc3f40adb2bNicolas Roard    , m_isLayerTile(isLayerTile)
608ad3ab0e47f0d5039e89c1873c178f538ec1b0dfChris Craik    , m_drawCount(0)
61f6a40880028cf495025747229c627f42e25acc66Chris Craik    , m_state(Unpainted)
62a5ffb7c279df240a07658953e1bd5df6d0480cb6Nicolas Roard{
63a5ffb7c279df240a07658953e1bd5df6d0480cb6Nicolas Roard#ifdef DEBUG_COUNT
64594c6b805969c2673c84d1d1d1a3556ce376ac7aChris Craik    ClassTracker::instance()->increment("Tile");
65a5ffb7c279df240a07658953e1bd5df6d0480cb6Nicolas Roard#endif
66c7e578330aece3c556ef205365c24676687223e2Derek Sollenberger    m_renderer = BaseRenderer::createRenderer();
67a5ffb7c279df240a07658953e1bd5df6d0480cb6Nicolas Roard}
68a5ffb7c279df240a07658953e1bd5df6d0480cb6Nicolas Roard
69594c6b805969c2673c84d1d1d1a3556ce376ac7aChris CraikTile::~Tile()
70a5ffb7c279df240a07658953e1bd5df6d0480cb6Nicolas Roard{
718ad3ab0e47f0d5039e89c1873c178f538ec1b0dfChris Craik    if (m_backTexture)
728ad3ab0e47f0d5039e89c1873c178f538ec1b0dfChris Craik        m_backTexture->release(this);
738ad3ab0e47f0d5039e89c1873c178f538ec1b0dfChris Craik    if (m_frontTexture)
748ad3ab0e47f0d5039e89c1873c178f538ec1b0dfChris Craik        m_frontTexture->release(this);
7590455eb70cca2df540942299b35bb3bd8261cb0bDerek Sollenberger
768dfdf8aa25b250ed3b8c0a443cf1cbaf9bd12c5bDerek Sollenberger    delete m_renderer;
778dfdf8aa25b250ed3b8c0a443cf1cbaf9bd12c5bDerek Sollenberger
78a5ffb7c279df240a07658953e1bd5df6d0480cb6Nicolas Roard#ifdef DEBUG_COUNT
79594c6b805969c2673c84d1d1d1a3556ce376ac7aChris Craik    ClassTracker::instance()->decrement("Tile");
80a5ffb7c279df240a07658953e1bd5df6d0480cb6Nicolas Roard#endif
81a5ffb7c279df240a07658953e1bd5df6d0480cb6Nicolas Roard}
82a5ffb7c279df240a07658953e1bd5df6d0480cb6Nicolas Roard
833a7a2aa023d51b1806d4063ab0ea5ef7d488556fNicolas Roard// All the following functions must be called from the main GL thread.
843a7a2aa023d51b1806d4063ab0ea5ef7d488556fNicolas Roard
85594c6b805969c2673c84d1d1d1a3556ce376ac7aChris Craikvoid Tile::setContents(int x, int y, float scale, bool isExpandedPrefetchTile)
86ffc715a2e6382fe9e331557c35fafc426507b8f5Derek Sollenberger{
87d8be9016b7fda67a91b4ee17b3b2e7ba692ee553Chris Craik    // TODO: investigate whether below check/discard is necessary
8892db4f76a7eca8f91084ec2eedde77b161786f23Chris Craik    if ((m_x != x)
893c131605fca8e29a88fdc4923d86bdc3f40adb2bNicolas Roard        || (m_y != y)
90f6a40880028cf495025747229c627f42e25acc66Chris Craik        || (m_scale != scale)) {
91f6a40880028cf495025747229c627f42e25acc66Chris Craik        // neither texture is relevant
92f6a40880028cf495025747229c627f42e25acc66Chris Craik        discardTextures();
93f6a40880028cf495025747229c627f42e25acc66Chris Craik    }
943c131605fca8e29a88fdc4923d86bdc3f40adb2bNicolas Roard
95f6a40880028cf495025747229c627f42e25acc66Chris Craik    android::AutoMutex lock(m_atomicSync);
96ffc715a2e6382fe9e331557c35fafc426507b8f5Derek Sollenberger    m_x = x;
97ffc715a2e6382fe9e331557c35fafc426507b8f5Derek Sollenberger    m_y = y;
983c131605fca8e29a88fdc4923d86bdc3f40adb2bNicolas Roard    m_scale = scale;
998ad3ab0e47f0d5039e89c1873c178f538ec1b0dfChris Craik    m_drawCount = TilesManager::instance()->getDrawGLCount();
100c51715092b8d3be1b51cce8bae61750cbcf342c4Chris Craik    if (isExpandedPrefetchTile)
101c51715092b8d3be1b51cce8bae61750cbcf342c4Chris Craik        m_drawCount--; // deprioritize expanded painting region
102ffc715a2e6382fe9e331557c35fafc426507b8f5Derek Sollenberger}
103ffc715a2e6382fe9e331557c35fafc426507b8f5Derek Sollenberger
104594c6b805969c2673c84d1d1d1a3556ce376ac7aChris Craikvoid Tile::reserveTexture()
105a5ffb7c279df240a07658953e1bd5df6d0480cb6Nicolas Roard{
106594c6b805969c2673c84d1d1d1a3556ce376ac7aChris Craik    TileTexture* texture = TilesManager::instance()->getAvailableTexture(this);
107a1e806ed3b2d9e2727d08cc2a3958fce501f6f33Derek Sollenberger
108a1e806ed3b2d9e2727d08cc2a3958fce501f6f33Derek Sollenberger    android::AutoMutex lock(m_atomicSync);
1098ad3ab0e47f0d5039e89c1873c178f538ec1b0dfChris Craik    if (texture && m_backTexture != texture) {
110d487c56b47c747d3e331ee1892e4c0473363afd2Chris Craik        ALOGV("tile %p reserving texture %p, back was %p (front %p)",
111d487c56b47c747d3e331ee1892e4c0473363afd2Chris Craik              this, texture, m_backTexture, m_frontTexture);
112f6a40880028cf495025747229c627f42e25acc66Chris Craik        m_state = Unpainted;
1138ad3ab0e47f0d5039e89c1873c178f538ec1b0dfChris Craik        m_backTexture = texture;
114a1e806ed3b2d9e2727d08cc2a3958fce501f6f33Derek Sollenberger    }
1156aa089bded6a1abbf8d61264588e1e3a32be31b3Chris Craik
116f6a40880028cf495025747229c627f42e25acc66Chris Craik    if (m_state == UpToDate) {
117d487c56b47c747d3e331ee1892e4c0473363afd2Chris Craik        ALOGV("moving tile %p to unpainted, since it reserved while up to date", this);
1186aa089bded6a1abbf8d61264588e1e3a32be31b3Chris Craik        m_dirty = true;
119f6a40880028cf495025747229c627f42e25acc66Chris Craik        m_state = Unpainted;
120f6a40880028cf495025747229c627f42e25acc66Chris Craik    }
121a5ffb7c279df240a07658953e1bd5df6d0480cb6Nicolas Roard}
122a5ffb7c279df240a07658953e1bd5df6d0480cb6Nicolas Roard
123594c6b805969c2673c84d1d1d1a3556ce376ac7aChris Craikbool Tile::removeTexture(TileTexture* texture)
124a5ffb7c279df240a07658953e1bd5df6d0480cb6Nicolas Roard{
1257b4a179bde698a856bed54a680438a9db3ff0566Chris Craik    ALOGV("%p removeTexture %p, back %p front %p",
1267b4a179bde698a856bed54a680438a9db3ff0566Chris Craik          this, texture, m_backTexture, m_frontTexture);
1273a7a2aa023d51b1806d4063ab0ea5ef7d488556fNicolas Roard    // We update atomically, so paintBitmap() can see the correct value
128a1e806ed3b2d9e2727d08cc2a3958fce501f6f33Derek Sollenberger    android::AutoMutex lock(m_atomicSync);
129f6a40880028cf495025747229c627f42e25acc66Chris Craik    if (m_frontTexture == texture) {
130f6a40880028cf495025747229c627f42e25acc66Chris Craik        if (m_state == UpToDate) {
131d487c56b47c747d3e331ee1892e4c0473363afd2Chris Craik            ALOGV("front texture removed, state was UpToDate, now becoming unpainted, bt is %p", m_backTexture);
132f6a40880028cf495025747229c627f42e25acc66Chris Craik            m_state = Unpainted;
133f6a40880028cf495025747229c627f42e25acc66Chris Craik        }
134f6a40880028cf495025747229c627f42e25acc66Chris Craik
1358ad3ab0e47f0d5039e89c1873c178f538ec1b0dfChris Craik        m_frontTexture = 0;
136f6a40880028cf495025747229c627f42e25acc66Chris Craik    }
137f6a40880028cf495025747229c627f42e25acc66Chris Craik    if (m_backTexture == texture) {
138f6a40880028cf495025747229c627f42e25acc66Chris Craik        m_state = Unpainted;
1398ad3ab0e47f0d5039e89c1873c178f538ec1b0dfChris Craik        m_backTexture = 0;
140f6a40880028cf495025747229c627f42e25acc66Chris Craik    }
1416aa089bded6a1abbf8d61264588e1e3a32be31b3Chris Craik
1426aa089bded6a1abbf8d61264588e1e3a32be31b3Chris Craik    // mark dirty regardless of which texture was taken - the back texture may
1436aa089bded6a1abbf8d61264588e1e3a32be31b3Chris Craik    // have been ready to swap
1446aa089bded6a1abbf8d61264588e1e3a32be31b3Chris Craik    m_dirty = true;
1456aa089bded6a1abbf8d61264588e1e3a32be31b3Chris Craik
14681ec1fafcb2c1bc433ec34b6ae4ea78d1ea7d3a8Nicolas Roard    return true;
1473a7a2aa023d51b1806d4063ab0ea5ef7d488556fNicolas Roard}
1483a7a2aa023d51b1806d4063ab0ea5ef7d488556fNicolas Roard
149594c6b805969c2673c84d1d1d1a3556ce376ac7aChris Craikvoid Tile::markAsDirty(const SkRegion& dirtyArea)
150a1e806ed3b2d9e2727d08cc2a3958fce501f6f33Derek Sollenberger{
151fa807bd31774157959640810e564fbe64338e8e3Nicolas Roard    if (dirtyArea.isEmpty())
152fa807bd31774157959640810e564fbe64338e8e3Nicolas Roard        return;
153a1e806ed3b2d9e2727d08cc2a3958fce501f6f33Derek Sollenberger    android::AutoMutex lock(m_atomicSync);
15462ee9670dd9beeb9a8f21d8737250c081382e2f5Teng-Hui Zhu    m_dirtyArea.op(dirtyArea, SkRegion::kUnion_Op);
15561a908361c8a96eeb70afdb5430e89845edb2bddNicolas Roard
15661a908361c8a96eeb70afdb5430e89845edb2bddNicolas Roard    // Check if we actually intersect with the area
15761a908361c8a96eeb70afdb5430e89845edb2bddNicolas Roard    bool intersect = false;
15861a908361c8a96eeb70afdb5430e89845edb2bddNicolas Roard    SkRegion::Iterator cliperator(dirtyArea);
15961a908361c8a96eeb70afdb5430e89845edb2bddNicolas Roard    SkRect realTileRect;
16061a908361c8a96eeb70afdb5430e89845edb2bddNicolas Roard    SkRect dirtyRect;
16161a908361c8a96eeb70afdb5430e89845edb2bddNicolas Roard    while (!cliperator.done()) {
16261a908361c8a96eeb70afdb5430e89845edb2bddNicolas Roard        dirtyRect.set(cliperator.rect());
163c51715092b8d3be1b51cce8bae61750cbcf342c4Chris Craik        if (intersectWithRect(m_x, m_y, TilesManager::tileWidth(), TilesManager::tileHeight(),
16461a908361c8a96eeb70afdb5430e89845edb2bddNicolas Roard                              m_scale, dirtyRect, realTileRect)) {
16561a908361c8a96eeb70afdb5430e89845edb2bddNicolas Roard            intersect = true;
16661a908361c8a96eeb70afdb5430e89845edb2bddNicolas Roard            break;
16761a908361c8a96eeb70afdb5430e89845edb2bddNicolas Roard        }
16861a908361c8a96eeb70afdb5430e89845edb2bddNicolas Roard        cliperator.next();
16961a908361c8a96eeb70afdb5430e89845edb2bddNicolas Roard    }
17008c253c5d2dad921120c3e1ab7bc6781064ca31bNicolas Roard
17161a908361c8a96eeb70afdb5430e89845edb2bddNicolas Roard    if (!intersect)
17261a908361c8a96eeb70afdb5430e89845edb2bddNicolas Roard        return;
17361a908361c8a96eeb70afdb5430e89845edb2bddNicolas Roard
17467e4aa15702646d5ff50e9524f4e63eb9ed20122Nicolas Roard    m_dirty = true;
175f6a40880028cf495025747229c627f42e25acc66Chris Craik    if (m_state == UpToDate) {
176f6a40880028cf495025747229c627f42e25acc66Chris Craik        // We only mark a tile as unpainted in 'markAsDirty' if its status is
177f6a40880028cf495025747229c627f42e25acc66Chris Craik        // UpToDate: marking dirty means we need to repaint, but don't stop the
178f6a40880028cf495025747229c627f42e25acc66Chris Craik        // current paint
179f6a40880028cf495025747229c627f42e25acc66Chris Craik        m_state = Unpainted;
180f6a40880028cf495025747229c627f42e25acc66Chris Craik    } else if (m_state != Unpainted) {
181f6a40880028cf495025747229c627f42e25acc66Chris Craik        // TODO: fix it so that they can paint while deferring the markAsDirty
182f6a40880028cf495025747229c627f42e25acc66Chris Craik        // call (or block updates)
1837b4a179bde698a856bed54a680438a9db3ff0566Chris Craik        ALOGV("Warning: tried to mark tile %p at %d, %d islayertile %d as dirty, state %d",
1847b4a179bde698a856bed54a680438a9db3ff0566Chris Craik              this, m_x, m_y, isLayerTile(), m_state);
185458b4b11924c3bcc70dcdd3d69f64a855870e72dChris Craik
186458b4b11924c3bcc70dcdd3d69f64a855870e72dChris Craik        // prefetch tiles can be marked dirty while in the process of painting,
187458b4b11924c3bcc70dcdd3d69f64a855870e72dChris Craik        // due to not using an update lock. force them to fail validate step.
188458b4b11924c3bcc70dcdd3d69f64a855870e72dChris Craik        m_state = Unpainted;
189f6a40880028cf495025747229c627f42e25acc66Chris Craik    }
190a1e806ed3b2d9e2727d08cc2a3958fce501f6f33Derek Sollenberger}
191a1e806ed3b2d9e2727d08cc2a3958fce501f6f33Derek Sollenberger
192594c6b805969c2673c84d1d1d1a3556ce376ac7aChris Craikbool Tile::isDirty()
193a1e806ed3b2d9e2727d08cc2a3958fce501f6f33Derek Sollenberger{
194a1e806ed3b2d9e2727d08cc2a3958fce501f6f33Derek Sollenberger    android::AutoMutex lock(m_atomicSync);
195a1e806ed3b2d9e2727d08cc2a3958fce501f6f33Derek Sollenberger    return m_dirty;
196a5ffb7c279df240a07658953e1bd5df6d0480cb6Nicolas Roard}
197a5ffb7c279df240a07658953e1bd5df6d0480cb6Nicolas Roard
198594c6b805969c2673c84d1d1d1a3556ce376ac7aChris Craikbool Tile::isRepaintPending()
199417789b7c56928a5fcb610583346d07ffa380900John Reck{
200417789b7c56928a5fcb610583346d07ffa380900John Reck    android::AutoMutex lock(m_atomicSync);
201417789b7c56928a5fcb610583346d07ffa380900John Reck    return m_repaintPending;
202417789b7c56928a5fcb610583346d07ffa380900John Reck}
203417789b7c56928a5fcb610583346d07ffa380900John Reck
204594c6b805969c2673c84d1d1d1a3556ce376ac7aChris Craikvoid Tile::setRepaintPending(bool pending)
205417789b7c56928a5fcb610583346d07ffa380900John Reck{
206417789b7c56928a5fcb610583346d07ffa380900John Reck    android::AutoMutex lock(m_atomicSync);
207417789b7c56928a5fcb610583346d07ffa380900John Reck    m_repaintPending = pending;
208417789b7c56928a5fcb610583346d07ffa380900John Reck}
209417789b7c56928a5fcb610583346d07ffa380900John Reck
210594c6b805969c2673c84d1d1d1a3556ce376ac7aChris Craikbool Tile::drawGL(float opacity, const SkRect& rect, float scale,
211594c6b805969c2673c84d1d1d1a3556ce376ac7aChris Craik                  const TransformationMatrix* transform)
212a5ffb7c279df240a07658953e1bd5df6d0480cb6Nicolas Roard{
2131deed5ff76dad5d0783c0e07639338f1d6b08a67Nicolas Roard    if (m_x < 0 || m_y < 0 || m_scale != scale)
214afe34397d6d4655c908f0995e760772980722da3Teng-Hui Zhu        return false;
21567e4aa15702646d5ff50e9524f4e63eb9ed20122Nicolas Roard
2168ad3ab0e47f0d5039e89c1873c178f538ec1b0dfChris Craik    // No need to mutex protect reads of m_backTexture as it is only written to by
217a1e806ed3b2d9e2727d08cc2a3958fce501f6f33Derek Sollenberger    // the consumer thread.
2188ad3ab0e47f0d5039e89c1873c178f538ec1b0dfChris Craik    if (!m_frontTexture)
219afe34397d6d4655c908f0995e760772980722da3Teng-Hui Zhu        return false;
220a5ffb7c279df240a07658953e1bd5df6d0480cb6Nicolas Roard
221f8f42bbda64a56cfd5ab48a274020d4efc9a5594Chris Craik    m_frontTexture->drawGL(isLayerTile(), rect, opacity, transform);
222afe34397d6d4655c908f0995e760772980722da3Teng-Hui Zhu    return true;
223a5ffb7c279df240a07658953e1bd5df6d0480cb6Nicolas Roard}
224a5ffb7c279df240a07658953e1bd5df6d0480cb6Nicolas Roard
225594c6b805969c2673c84d1d1d1a3556ce376ac7aChris Craikbool Tile::isTileReady()
226a5ffb7c279df240a07658953e1bd5df6d0480cb6Nicolas Roard{
2278ad3ab0e47f0d5039e89c1873c178f538ec1b0dfChris Craik    // Return true if the tile's most recently drawn texture is up to date
2288ad3ab0e47f0d5039e89c1873c178f538ec1b0dfChris Craik    android::AutoMutex lock(m_atomicSync);
229594c6b805969c2673c84d1d1d1a3556ce376ac7aChris Craik    TileTexture * texture = (m_state == ReadyToSwap) ? m_backTexture : m_frontTexture;
2308ad3ab0e47f0d5039e89c1873c178f538ec1b0dfChris Craik
2318ad3ab0e47f0d5039e89c1873c178f538ec1b0dfChris Craik    if (!texture)
232a5ffb7c279df240a07658953e1bd5df6d0480cb6Nicolas Roard        return false;
2338ad3ab0e47f0d5039e89c1873c178f538ec1b0dfChris Craik
2348ad3ab0e47f0d5039e89c1873c178f538ec1b0dfChris Craik    if (texture->owner() != this)
235a5ffb7c279df240a07658953e1bd5df6d0480cb6Nicolas Roard        return false;
236a1e806ed3b2d9e2727d08cc2a3958fce501f6f33Derek Sollenberger
23767e4aa15702646d5ff50e9524f4e63eb9ed20122Nicolas Roard    if (m_dirty)
23867e4aa15702646d5ff50e9524f4e63eb9ed20122Nicolas Roard        return false;
23967e4aa15702646d5ff50e9524f4e63eb9ed20122Nicolas Roard
240f6a40880028cf495025747229c627f42e25acc66Chris Craik    if (m_state != ReadyToSwap && m_state != UpToDate)
241f6a40880028cf495025747229c627f42e25acc66Chris Craik        return false;
242f6a40880028cf495025747229c627f42e25acc66Chris Craik
243f8f42bbda64a56cfd5ab48a274020d4efc9a5594Chris Craik    return true;
244a5ffb7c279df240a07658953e1bd5df6d0480cb6Nicolas Roard}
245a5ffb7c279df240a07658953e1bd5df6d0480cb6Nicolas Roard
246594c6b805969c2673c84d1d1d1a3556ce376ac7aChris Craikbool Tile::intersectWithRect(int x, int y, int tileWidth, int tileHeight,
247594c6b805969c2673c84d1d1d1a3556ce376ac7aChris Craik                             float scale, const SkRect& dirtyRect,
248594c6b805969c2673c84d1d1d1a3556ce376ac7aChris Craik                             SkRect& realTileRect)
249fa807bd31774157959640810e564fbe64338e8e3Nicolas Roard{
250fa807bd31774157959640810e564fbe64338e8e3Nicolas Roard    // compute the rect to corresponds to pixels
251fa807bd31774157959640810e564fbe64338e8e3Nicolas Roard    realTileRect.fLeft = x * tileWidth;
252fa807bd31774157959640810e564fbe64338e8e3Nicolas Roard    realTileRect.fTop = y * tileHeight;
253fa807bd31774157959640810e564fbe64338e8e3Nicolas Roard    realTileRect.fRight = realTileRect.fLeft + tileWidth;
254fa807bd31774157959640810e564fbe64338e8e3Nicolas Roard    realTileRect.fBottom = realTileRect.fTop + tileHeight;
255fa807bd31774157959640810e564fbe64338e8e3Nicolas Roard
256fa807bd31774157959640810e564fbe64338e8e3Nicolas Roard    // scale the dirtyRect for intersect computation.
257fa807bd31774157959640810e564fbe64338e8e3Nicolas Roard    SkRect realDirtyRect = SkRect::MakeWH(dirtyRect.width() * scale,
258fa807bd31774157959640810e564fbe64338e8e3Nicolas Roard                                          dirtyRect.height() * scale);
259fa807bd31774157959640810e564fbe64338e8e3Nicolas Roard    realDirtyRect.offset(dirtyRect.fLeft * scale, dirtyRect.fTop * scale);
260fa807bd31774157959640810e564fbe64338e8e3Nicolas Roard
261fa807bd31774157959640810e564fbe64338e8e3Nicolas Roard    if (!realTileRect.intersect(realDirtyRect))
262fa807bd31774157959640810e564fbe64338e8e3Nicolas Roard        return false;
263fa807bd31774157959640810e564fbe64338e8e3Nicolas Roard    return true;
264fa807bd31774157959640810e564fbe64338e8e3Nicolas Roard}
265fa807bd31774157959640810e564fbe64338e8e3Nicolas Roard
266594c6b805969c2673c84d1d1d1a3556ce376ac7aChris Craikbool Tile::isTileVisible(const IntRect& viewTileBounds)
267e48d27773894f36d85e5c2e2052ab90d502e1c72Chris Craik{
268e48d27773894f36d85e5c2e2052ab90d502e1c72Chris Craik    return (m_x >= viewTileBounds.x()
269e48d27773894f36d85e5c2e2052ab90d502e1c72Chris Craik            && m_x < viewTileBounds.x() + viewTileBounds.width()
270e48d27773894f36d85e5c2e2052ab90d502e1c72Chris Craik            && m_y >= viewTileBounds.y()
271e48d27773894f36d85e5c2e2052ab90d502e1c72Chris Craik            && m_y < viewTileBounds.y() + viewTileBounds.height());
272e48d27773894f36d85e5c2e2052ab90d502e1c72Chris Craik}
273e48d27773894f36d85e5c2e2052ab90d502e1c72Chris Craik
2743a7a2aa023d51b1806d4063ab0ea5ef7d488556fNicolas Roard// This is called from the texture generation thread
275594c6b805969c2673c84d1d1d1a3556ce376ac7aChris Craikvoid Tile::paintBitmap(TilePainter* painter)
276a5ffb7c279df240a07658953e1bd5df6d0480cb6Nicolas Roard{
277a1e806ed3b2d9e2727d08cc2a3958fce501f6f33Derek Sollenberger    // We acquire the values below atomically. This ensures that we are reading
278a1e806ed3b2d9e2727d08cc2a3958fce501f6f33Derek Sollenberger    // values correctly across cores. Further, once we have these values they
279a1e806ed3b2d9e2727d08cc2a3958fce501f6f33Derek Sollenberger    // can be updated by other threads without consequence.
280a1e806ed3b2d9e2727d08cc2a3958fce501f6f33Derek Sollenberger    m_atomicSync.lock();
281a1e806ed3b2d9e2727d08cc2a3958fce501f6f33Derek Sollenberger    bool dirty = m_dirty;
282594c6b805969c2673c84d1d1d1a3556ce376ac7aChris Craik    TileTexture* texture = m_backTexture;
28362ee9670dd9beeb9a8f21d8737250c081382e2f5Teng-Hui Zhu    SkRegion dirtyArea = m_dirtyArea;
2843a7a2aa023d51b1806d4063ab0ea5ef7d488556fNicolas Roard    float scale = m_scale;
285be61abb47b98988ca94bd839a1e17c3267365dc9Nicolas Roard    const int x = m_x;
286be61abb47b98988ca94bd839a1e17c3267365dc9Nicolas Roard    const int y = m_y;
287cf1ae53e7b2853d1148ecd784379f12dffda9d43Nicolas Roard
2883c131605fca8e29a88fdc4923d86bdc3f40adb2bNicolas Roard    if (!dirty || !texture) {
2893c131605fca8e29a88fdc4923d86bdc3f40adb2bNicolas Roard        m_atomicSync.unlock();
29075394f5ee0aac2337cdff1597b4e686e22c52833Nicolas Roard        return;
2913c131605fca8e29a88fdc4923d86bdc3f40adb2bNicolas Roard    }
292f6a40880028cf495025747229c627f42e25acc66Chris Craik    if (m_state != Unpainted) {
293d487c56b47c747d3e331ee1892e4c0473363afd2Chris Craik        ALOGV("Warning: started painting tile %p, but was at state %d, ft %p bt %p",
294f6a40880028cf495025747229c627f42e25acc66Chris Craik              this, m_state, m_frontTexture, m_backTexture);
295f6a40880028cf495025747229c627f42e25acc66Chris Craik    }
296f6a40880028cf495025747229c627f42e25acc66Chris Craik    m_state = PaintingStarted;
29762ee9670dd9beeb9a8f21d8737250c081382e2f5Teng-Hui Zhu    TextureInfo* textureInfo = texture->getTextureInfo();
2983c131605fca8e29a88fdc4923d86bdc3f40adb2bNicolas Roard    m_atomicSync.unlock();
299a52793c453c1512d0a18d4ae3108a975f998ae45Derek Sollenberger
300a1e806ed3b2d9e2727d08cc2a3958fce501f6f33Derek Sollenberger    // at this point we can safely check the ownership (if the texture got
301594c6b805969c2673c84d1d1d1a3556ce376ac7aChris Craik    // transferred to another Tile under us)
3028ad3ab0e47f0d5039e89c1873c178f538ec1b0dfChris Craik    if (texture->owner() != this) {
30375394f5ee0aac2337cdff1597b4e686e22c52833Nicolas Roard        return;
304a5ffb7c279df240a07658953e1bd5df6d0480cb6Nicolas Roard    }
305a5ffb7c279df240a07658953e1bd5df6d0480cb6Nicolas Roard
306c7e578330aece3c556ef205365c24676687223e2Derek Sollenberger    // swap out the renderer if necessary
307c7e578330aece3c556ef205365c24676687223e2Derek Sollenberger    BaseRenderer::swapRendererIfNeeded(m_renderer);
308232d0b3572d13d9b4fb1211d9d56252a1ede3ed6Derek Sollenberger    // setup the common renderInfo fields;
309232d0b3572d13d9b4fb1211d9d56252a1ede3ed6Derek Sollenberger    TileRenderInfo renderInfo;
310232d0b3572d13d9b4fb1211d9d56252a1ede3ed6Derek Sollenberger    renderInfo.x = x;
311232d0b3572d13d9b4fb1211d9d56252a1ede3ed6Derek Sollenberger    renderInfo.y = y;
312232d0b3572d13d9b4fb1211d9d56252a1ede3ed6Derek Sollenberger    renderInfo.scale = scale;
313232d0b3572d13d9b4fb1211d9d56252a1ede3ed6Derek Sollenberger    renderInfo.tileSize = texture->getSize();
3143c131605fca8e29a88fdc4923d86bdc3f40adb2bNicolas Roard    renderInfo.tilePainter = painter;
3153c131605fca8e29a88fdc4923d86bdc3f40adb2bNicolas Roard    renderInfo.baseTile = this;
316232d0b3572d13d9b4fb1211d9d56252a1ede3ed6Derek Sollenberger    renderInfo.textureInfo = textureInfo;
317232d0b3572d13d9b4fb1211d9d56252a1ede3ed6Derek Sollenberger
318232d0b3572d13d9b4fb1211d9d56252a1ede3ed6Derek Sollenberger    const float tileWidth = renderInfo.tileSize.width();
319232d0b3572d13d9b4fb1211d9d56252a1ede3ed6Derek Sollenberger    const float tileHeight = renderInfo.tileSize.height();
320232d0b3572d13d9b4fb1211d9d56252a1ede3ed6Derek Sollenberger
32167e4aa15702646d5ff50e9524f4e63eb9ed20122Nicolas Roard    SkRegion::Iterator cliperator(dirtyArea);
32267e4aa15702646d5ff50e9524f4e63eb9ed20122Nicolas Roard
32367e4aa15702646d5ff50e9524f4e63eb9ed20122Nicolas Roard    bool fullRepaint = false;
324f85cf343a02e85633e6b68c7f5db3c033b780607Teng-Hui Zhu
32562ee9670dd9beeb9a8f21d8737250c081382e2f5Teng-Hui Zhu    if (m_fullRepaint
326f85cf343a02e85633e6b68c7f5db3c033b780607Teng-Hui Zhu        || textureInfo->m_width != tileWidth
327fa807bd31774157959640810e564fbe64338e8e3Nicolas Roard        || textureInfo->m_height != tileHeight) {
32867e4aa15702646d5ff50e9524f4e63eb9ed20122Nicolas Roard        fullRepaint = true;
329fca6a67b130c1f97d366460af412ec6e6de14834Derek Sollenberger    }
33067e4aa15702646d5ff50e9524f4e63eb9ed20122Nicolas Roard
331c048426c23be795d3bf870e47429167b4157a2d6Nicolas Roard    // For now, only do full repaint
33262ee9670dd9beeb9a8f21d8737250c081382e2f5Teng-Hui Zhu    fullRepaint = true;
3335d77d7f575389ee1f20a394c635928c2e75667c7Nicolas Roard
334c048426c23be795d3bf870e47429167b4157a2d6Nicolas Roard    if (!fullRepaint) {
335c048426c23be795d3bf870e47429167b4157a2d6Nicolas Roard        // compute the partial inval area
336c048426c23be795d3bf870e47429167b4157a2d6Nicolas Roard        SkIRect totalRect;
337c048426c23be795d3bf870e47429167b4157a2d6Nicolas Roard        totalRect.set(0, 0, 0, 0);
338c048426c23be795d3bf870e47429167b4157a2d6Nicolas Roard        float tileSurface = tileWidth * tileHeight;
339c048426c23be795d3bf870e47429167b4157a2d6Nicolas Roard        float tileSurfaceCap = MAX_INVAL_AREA * tileSurface;
340c048426c23be795d3bf870e47429167b4157a2d6Nicolas Roard
341c048426c23be795d3bf870e47429167b4157a2d6Nicolas Roard        // We join all the invals in the same tile for now
342c048426c23be795d3bf870e47429167b4157a2d6Nicolas Roard        while (!fullRepaint && !cliperator.done()) {
343c048426c23be795d3bf870e47429167b4157a2d6Nicolas Roard            SkRect realTileRect;
344c048426c23be795d3bf870e47429167b4157a2d6Nicolas Roard            SkRect dirtyRect;
345c048426c23be795d3bf870e47429167b4157a2d6Nicolas Roard            dirtyRect.set(cliperator.rect());
346c048426c23be795d3bf870e47429167b4157a2d6Nicolas Roard            bool intersect = intersectWithRect(x, y, tileWidth, tileHeight,
347c048426c23be795d3bf870e47429167b4157a2d6Nicolas Roard                                               scale, dirtyRect, realTileRect);
348c048426c23be795d3bf870e47429167b4157a2d6Nicolas Roard            if (intersect) {
349c048426c23be795d3bf870e47429167b4157a2d6Nicolas Roard                // initialize finalRealRect to the rounded values of realTileRect
350c048426c23be795d3bf870e47429167b4157a2d6Nicolas Roard                SkIRect finalRealRect;
351c048426c23be795d3bf870e47429167b4157a2d6Nicolas Roard                realTileRect.roundOut(&finalRealRect);
352c048426c23be795d3bf870e47429167b4157a2d6Nicolas Roard
353c048426c23be795d3bf870e47429167b4157a2d6Nicolas Roard                // stash the int values of the current width and height
354c048426c23be795d3bf870e47429167b4157a2d6Nicolas Roard                const int iWidth = finalRealRect.width();
355c048426c23be795d3bf870e47429167b4157a2d6Nicolas Roard                const int iHeight = finalRealRect.height();
356c048426c23be795d3bf870e47429167b4157a2d6Nicolas Roard
357c048426c23be795d3bf870e47429167b4157a2d6Nicolas Roard                if (iWidth == tileWidth || iHeight == tileHeight) {
358c048426c23be795d3bf870e47429167b4157a2d6Nicolas Roard                    fullRepaint = true;
359c048426c23be795d3bf870e47429167b4157a2d6Nicolas Roard                    break;
360c048426c23be795d3bf870e47429167b4157a2d6Nicolas Roard                }
361c048426c23be795d3bf870e47429167b4157a2d6Nicolas Roard
362c048426c23be795d3bf870e47429167b4157a2d6Nicolas Roard                // translate the rect into tile space coordinates
363c048426c23be795d3bf870e47429167b4157a2d6Nicolas Roard                finalRealRect.fLeft = finalRealRect.fLeft % static_cast<int>(tileWidth);
364c048426c23be795d3bf870e47429167b4157a2d6Nicolas Roard                finalRealRect.fTop = finalRealRect.fTop % static_cast<int>(tileHeight);
365c048426c23be795d3bf870e47429167b4157a2d6Nicolas Roard                finalRealRect.fRight = finalRealRect.fLeft + iWidth;
366c048426c23be795d3bf870e47429167b4157a2d6Nicolas Roard                finalRealRect.fBottom = finalRealRect.fTop + iHeight;
367c048426c23be795d3bf870e47429167b4157a2d6Nicolas Roard                totalRect.join(finalRealRect);
368c048426c23be795d3bf870e47429167b4157a2d6Nicolas Roard                float repaintSurface = totalRect.width() * totalRect.height();
369c048426c23be795d3bf870e47429167b4157a2d6Nicolas Roard
370c048426c23be795d3bf870e47429167b4157a2d6Nicolas Roard                if (repaintSurface > tileSurfaceCap) {
371c048426c23be795d3bf870e47429167b4157a2d6Nicolas Roard                    fullRepaint = true;
372c048426c23be795d3bf870e47429167b4157a2d6Nicolas Roard                    break;
373c048426c23be795d3bf870e47429167b4157a2d6Nicolas Roard                }
374fca6a67b130c1f97d366460af412ec6e6de14834Derek Sollenberger            }
375fca6a67b130c1f97d366460af412ec6e6de14834Derek Sollenberger
376c048426c23be795d3bf870e47429167b4157a2d6Nicolas Roard            cliperator.next();
377c048426c23be795d3bf870e47429167b4157a2d6Nicolas Roard        }
37867e4aa15702646d5ff50e9524f4e63eb9ed20122Nicolas Roard
379c048426c23be795d3bf870e47429167b4157a2d6Nicolas Roard        if (!fullRepaint) {
380c048426c23be795d3bf870e47429167b4157a2d6Nicolas Roard            renderInfo.invalRect = &totalRect;
381f7ad77dc2a981834d664fd24022c3dfade69c8aaChris Craik            m_renderer->renderTiledContent(renderInfo);
38267e4aa15702646d5ff50e9524f4e63eb9ed20122Nicolas Roard        }
38367e4aa15702646d5ff50e9524f4e63eb9ed20122Nicolas Roard    }
384fca6a67b130c1f97d366460af412ec6e6de14834Derek Sollenberger
385fa807bd31774157959640810e564fbe64338e8e3Nicolas Roard    // Do a full repaint if needed
386fca6a67b130c1f97d366460af412ec6e6de14834Derek Sollenberger    if (fullRepaint) {
387c048426c23be795d3bf870e47429167b4157a2d6Nicolas Roard        renderInfo.invalRect = 0;
388f7ad77dc2a981834d664fd24022c3dfade69c8aaChris Craik        m_renderer->renderTiledContent(renderInfo);
389fca6a67b130c1f97d366460af412ec6e6de14834Derek Sollenberger    }
390fca6a67b130c1f97d366460af412ec6e6de14834Derek Sollenberger
39167e4aa15702646d5ff50e9524f4e63eb9ed20122Nicolas Roard    m_atomicSync.lock();
3927c554a61cb935660cdc86905d040c781b490150fTeng-Hui Zhu
3938ad3ab0e47f0d5039e89c1873c178f538ec1b0dfChris Craik    if (texture == m_backTexture) {
3945ba4a087b9212ca9ae083f015637f417199d85ccJohn Reck        // set the fullrepaint flags
39562ee9670dd9beeb9a8f21d8737250c081382e2f5Teng-Hui Zhu        m_fullRepaint = false;
39667e4aa15702646d5ff50e9524f4e63eb9ed20122Nicolas Roard
3975ba4a087b9212ca9ae083f015637f417199d85ccJohn Reck        // The various checks to see if we are still dirty...
39867e4aa15702646d5ff50e9524f4e63eb9ed20122Nicolas Roard
3995ba4a087b9212ca9ae083f015637f417199d85ccJohn Reck        m_dirty = false;
40067e4aa15702646d5ff50e9524f4e63eb9ed20122Nicolas Roard
4015ba4a087b9212ca9ae083f015637f417199d85ccJohn Reck        if (m_scale != scale)
4025ba4a087b9212ca9ae083f015637f417199d85ccJohn Reck            m_dirty = true;
40367e4aa15702646d5ff50e9524f4e63eb9ed20122Nicolas Roard
404fca6a67b130c1f97d366460af412ec6e6de14834Derek Sollenberger        if (fullRepaint)
40562ee9670dd9beeb9a8f21d8737250c081382e2f5Teng-Hui Zhu            m_dirtyArea.setEmpty();
406fca6a67b130c1f97d366460af412ec6e6de14834Derek Sollenberger        else
40762ee9670dd9beeb9a8f21d8737250c081382e2f5Teng-Hui Zhu            m_dirtyArea.op(dirtyArea, SkRegion::kDifference_Op);
40867e4aa15702646d5ff50e9524f4e63eb9ed20122Nicolas Roard
40962ee9670dd9beeb9a8f21d8737250c081382e2f5Teng-Hui Zhu        if (!m_dirtyArea.isEmpty())
4105ba4a087b9212ca9ae083f015637f417199d85ccJohn Reck            m_dirty = true;
411c15781f45f0d19a925be7fd73bd10c318562db70Nicolas Roard
412d487c56b47c747d3e331ee1892e4c0473363afd2Chris Craik        ALOGV("painted tile %p (%d, %d), texture %p, dirty=%d", this, x, y, texture, m_dirty);
413e733717c7b60d2ccfee9c47af4659ffb8e70dd73Chris Craik
414f6a40880028cf495025747229c627f42e25acc66Chris Craik        validatePaint();
415f6a40880028cf495025747229c627f42e25acc66Chris Craik    } else {
416d487c56b47c747d3e331ee1892e4c0473363afd2Chris Craik        ALOGV("tile %p no longer owns texture %p, m_state %d. ft %p bt %p",
417d487c56b47c747d3e331ee1892e4c0473363afd2Chris Craik              this, texture, m_state, m_frontTexture, m_backTexture);
4185ba4a087b9212ca9ae083f015637f417199d85ccJohn Reck    }
41967e4aa15702646d5ff50e9524f4e63eb9ed20122Nicolas Roard
42067e4aa15702646d5ff50e9524f4e63eb9ed20122Nicolas Roard    m_atomicSync.unlock();
42167e4aa15702646d5ff50e9524f4e63eb9ed20122Nicolas Roard}
42267e4aa15702646d5ff50e9524f4e63eb9ed20122Nicolas Roard
423594c6b805969c2673c84d1d1d1a3556ce376ac7aChris Craikvoid Tile::discardTextures() {
4248ad3ab0e47f0d5039e89c1873c178f538ec1b0dfChris Craik    android::AutoMutex lock(m_atomicSync);
425d487c56b47c747d3e331ee1892e4c0473363afd2Chris Craik    ALOGV("%p discarding bt %p, ft %p",
426d487c56b47c747d3e331ee1892e4c0473363afd2Chris Craik          this, m_backTexture, m_frontTexture);
4278ad3ab0e47f0d5039e89c1873c178f538ec1b0dfChris Craik    if (m_frontTexture) {
4288ad3ab0e47f0d5039e89c1873c178f538ec1b0dfChris Craik        m_frontTexture->release(this);
4298ad3ab0e47f0d5039e89c1873c178f538ec1b0dfChris Craik        m_frontTexture = 0;
4308ad3ab0e47f0d5039e89c1873c178f538ec1b0dfChris Craik    }
4318ad3ab0e47f0d5039e89c1873c178f538ec1b0dfChris Craik    if (m_backTexture) {
4328ad3ab0e47f0d5039e89c1873c178f538ec1b0dfChris Craik        m_backTexture->release(this);
4338ad3ab0e47f0d5039e89c1873c178f538ec1b0dfChris Craik        m_backTexture = 0;
4348ad3ab0e47f0d5039e89c1873c178f538ec1b0dfChris Craik    }
43562ee9670dd9beeb9a8f21d8737250c081382e2f5Teng-Hui Zhu    m_dirtyArea.setEmpty();
43662ee9670dd9beeb9a8f21d8737250c081382e2f5Teng-Hui Zhu    m_fullRepaint = true;
43762ee9670dd9beeb9a8f21d8737250c081382e2f5Teng-Hui Zhu
4388ad3ab0e47f0d5039e89c1873c178f538ec1b0dfChris Craik    m_dirty = true;
439f6a40880028cf495025747229c627f42e25acc66Chris Craik    m_state = Unpainted;
4408ad3ab0e47f0d5039e89c1873c178f538ec1b0dfChris Craik}
4418ad3ab0e47f0d5039e89c1873c178f538ec1b0dfChris Craik
442594c6b805969c2673c84d1d1d1a3556ce376ac7aChris Craikvoid Tile::discardBackTexture() {
4433a819aac70dd26f675644f6a35b13be5fb3de2f1Chris Craik    android::AutoMutex lock(m_atomicSync);
4443a819aac70dd26f675644f6a35b13be5fb3de2f1Chris Craik    if (m_backTexture) {
4453a819aac70dd26f675644f6a35b13be5fb3de2f1Chris Craik        m_backTexture->release(this);
4463a819aac70dd26f675644f6a35b13be5fb3de2f1Chris Craik        m_backTexture = 0;
4473a819aac70dd26f675644f6a35b13be5fb3de2f1Chris Craik    }
4483ef9d5cc655b8274860b8d15441201d3e621baf5Chris Craik    m_state = Unpainted;
4493ef9d5cc655b8274860b8d15441201d3e621baf5Chris Craik    m_dirty = true;
4503a819aac70dd26f675644f6a35b13be5fb3de2f1Chris Craik}
4513a819aac70dd26f675644f6a35b13be5fb3de2f1Chris Craik
452594c6b805969c2673c84d1d1d1a3556ce376ac7aChris Craikbool Tile::swapTexturesIfNeeded() {
4538ad3ab0e47f0d5039e89c1873c178f538ec1b0dfChris Craik    android::AutoMutex lock(m_atomicSync);
454f6a40880028cf495025747229c627f42e25acc66Chris Craik    if (m_state == ReadyToSwap) {
4558ad3ab0e47f0d5039e89c1873c178f538ec1b0dfChris Craik        // discard old texture and swap the new one in its place
4568ad3ab0e47f0d5039e89c1873c178f538ec1b0dfChris Craik        if (m_frontTexture)
4578ad3ab0e47f0d5039e89c1873c178f538ec1b0dfChris Craik            m_frontTexture->release(this);
4588ad3ab0e47f0d5039e89c1873c178f538ec1b0dfChris Craik
4598ad3ab0e47f0d5039e89c1873c178f538ec1b0dfChris Craik        m_frontTexture = m_backTexture;
4608ad3ab0e47f0d5039e89c1873c178f538ec1b0dfChris Craik        m_backTexture = 0;
461f6a40880028cf495025747229c627f42e25acc66Chris Craik        m_state = UpToDate;
462d487c56b47c747d3e331ee1892e4c0473363afd2Chris Craik        ALOGV("display texture for %p at %d, %d front is now %p, back is %p",
463d487c56b47c747d3e331ee1892e4c0473363afd2Chris Craik              this, m_x, m_y, m_frontTexture, m_backTexture);
464f6a40880028cf495025747229c627f42e25acc66Chris Craik
4658ad3ab0e47f0d5039e89c1873c178f538ec1b0dfChris Craik        return true;
4668ad3ab0e47f0d5039e89c1873c178f538ec1b0dfChris Craik    }
4678ad3ab0e47f0d5039e89c1873c178f538ec1b0dfChris Craik    return false;
4688ad3ab0e47f0d5039e89c1873c178f538ec1b0dfChris Craik}
4698ad3ab0e47f0d5039e89c1873c178f538ec1b0dfChris Craik
470594c6b805969c2673c84d1d1d1a3556ce376ac7aChris Craikvoid Tile::backTextureTransfer() {
471f6a40880028cf495025747229c627f42e25acc66Chris Craik    android::AutoMutex lock(m_atomicSync);
472f6a40880028cf495025747229c627f42e25acc66Chris Craik    if (m_state == PaintingStarted)
473f6a40880028cf495025747229c627f42e25acc66Chris Craik        m_state = TransferredUnvalidated;
474f6a40880028cf495025747229c627f42e25acc66Chris Craik    else if (m_state == ValidatedUntransferred)
475f6a40880028cf495025747229c627f42e25acc66Chris Craik        m_state = ReadyToSwap;
476f6a40880028cf495025747229c627f42e25acc66Chris Craik    else {
477f6a40880028cf495025747229c627f42e25acc66Chris Craik        // shouldn't have transferred a tile in any other state, log
478d487c56b47c747d3e331ee1892e4c0473363afd2Chris Craik        ALOGV("Note: transferred tile %p at %d %d, state wasn't paintingstarted or validated: %d",
479d487c56b47c747d3e331ee1892e4c0473363afd2Chris Craik              this, m_x, m_y, m_state);
480f6a40880028cf495025747229c627f42e25acc66Chris Craik    }
481f6a40880028cf495025747229c627f42e25acc66Chris Craik}
482f6a40880028cf495025747229c627f42e25acc66Chris Craik
483594c6b805969c2673c84d1d1d1a3556ce376ac7aChris Craikvoid Tile::backTextureTransferFail() {
484530c83c6351e05a6939ad0b5bc291da073e77b5bChris Craik    // transfer failed for some reason, mark dirty so it will (repaint and) be
485530c83c6351e05a6939ad0b5bc291da073e77b5bChris Craik    // retransferred.
486530c83c6351e05a6939ad0b5bc291da073e77b5bChris Craik    android::AutoMutex lock(m_atomicSync);
487530c83c6351e05a6939ad0b5bc291da073e77b5bChris Craik    m_state = Unpainted;
4883ef9d5cc655b8274860b8d15441201d3e621baf5Chris Craik    m_dirty = true;
489530c83c6351e05a6939ad0b5bc291da073e77b5bChris Craik    // whether validatePaint is called before or after, it won't do anything
490530c83c6351e05a6939ad0b5bc291da073e77b5bChris Craik}
491530c83c6351e05a6939ad0b5bc291da073e77b5bChris Craik
492594c6b805969c2673c84d1d1d1a3556ce376ac7aChris Craikvoid Tile::validatePaint() {
493f6a40880028cf495025747229c627f42e25acc66Chris Craik    // ONLY CALL while m_atomicSync is locked (at the end of paintBitmap())
494f6a40880028cf495025747229c627f42e25acc66Chris Craik
495f6a40880028cf495025747229c627f42e25acc66Chris Craik    if (!m_dirty) {
496f6a40880028cf495025747229c627f42e25acc66Chris Craik        // since after the paint, the tile isn't dirty, 'validate' it - this
497f6a40880028cf495025747229c627f42e25acc66Chris Craik        // may happed before or after the transfer queue operation. Only
498f6a40880028cf495025747229c627f42e25acc66Chris Craik        // when both have happened, mark as 'ReadyToSwap'
499f6a40880028cf495025747229c627f42e25acc66Chris Craik        if (m_state == PaintingStarted)
500f6a40880028cf495025747229c627f42e25acc66Chris Craik            m_state = ValidatedUntransferred;
501309ae897e0ad3493fc6acd97a39c631f90580d57Teng-Hui Zhu        else if (m_state == TransferredUnvalidated) {
5028abedfb0681eb18f62137fffde000a9dbb75c4d2Teng-Hui Zhu            // When the backTexture has been marked pureColor, we will skip the
5038abedfb0681eb18f62137fffde000a9dbb75c4d2Teng-Hui Zhu            // transfer and marked as ReadyToSwap, in this case, we don't want
5048abedfb0681eb18f62137fffde000a9dbb75c4d2Teng-Hui Zhu            // to reset m_dirty bit to true.
505f6a40880028cf495025747229c627f42e25acc66Chris Craik            m_state = ReadyToSwap;
5068abedfb0681eb18f62137fffde000a9dbb75c4d2Teng-Hui Zhu        } else {
507d487c56b47c747d3e331ee1892e4c0473363afd2Chris Craik            ALOGV("Note: validated tile %p at %d %d, state wasn't paintingstarted or transferred %d",
508f6a40880028cf495025747229c627f42e25acc66Chris Craik                  this, m_x, m_y, m_state);
5093ef9d5cc655b8274860b8d15441201d3e621baf5Chris Craik            // failed transferring, in which case mark dirty (since
5103ef9d5cc655b8274860b8d15441201d3e621baf5Chris Craik            // paintBitmap() may have cleared m_dirty)
5113ef9d5cc655b8274860b8d15441201d3e621baf5Chris Craik            m_dirty = true;
512f6a40880028cf495025747229c627f42e25acc66Chris Craik        }
513f6a40880028cf495025747229c627f42e25acc66Chris Craik
514f6a40880028cf495025747229c627f42e25acc66Chris Craik        if (m_deferredDirty) {
515d487c56b47c747d3e331ee1892e4c0473363afd2Chris Craik            ALOGV("Note: deferred dirty flag set, possibly a missed paint on tile %p", this);
516f6a40880028cf495025747229c627f42e25acc66Chris Craik            m_deferredDirty = false;
517f6a40880028cf495025747229c627f42e25acc66Chris Craik        }
518f6a40880028cf495025747229c627f42e25acc66Chris Craik    } else {
519d487c56b47c747d3e331ee1892e4c0473363afd2Chris Craik        ALOGV("Note: paint was unsuccessful.");
520f6a40880028cf495025747229c627f42e25acc66Chris Craik        m_state = Unpainted;
521f6a40880028cf495025747229c627f42e25acc66Chris Craik    }
522f6a40880028cf495025747229c627f42e25acc66Chris Craik
523f6a40880028cf495025747229c627f42e25acc66Chris Craik}
524f6a40880028cf495025747229c627f42e25acc66Chris Craik
525a5ffb7c279df240a07658953e1bd5df6d0480cb6Nicolas Roard} // namespace WebCore
526a5ffb7c279df240a07658953e1bd5df6d0480cb6Nicolas Roard
527a5ffb7c279df240a07658953e1bd5df6d0480cb6Nicolas Roard#endif // USE(ACCELERATED_COMPOSITING)
528