Tile.cpp revision 32ce41e0241790f20e63cafea4d3c1db87423eec
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,
211a31d28d03260660f592ad6914f5375b47e823aa5Teng-Hui Zhu                  const TransformationMatrix* transform,
21232ce41e0241790f20e63cafea4d3c1db87423eecChris Craik                  bool forceBlending, bool usePointSampling,
21332ce41e0241790f20e63cafea4d3c1db87423eecChris Craik                  const FloatPoint& fillPortion)
214a5ffb7c279df240a07658953e1bd5df6d0480cb6Nicolas Roard{
2151deed5ff76dad5d0783c0e07639338f1d6b08a67Nicolas Roard    if (m_x < 0 || m_y < 0 || m_scale != scale)
216afe34397d6d4655c908f0995e760772980722da3Teng-Hui Zhu        return false;
21767e4aa15702646d5ff50e9524f4e63eb9ed20122Nicolas Roard
2188ad3ab0e47f0d5039e89c1873c178f538ec1b0dfChris Craik    // No need to mutex protect reads of m_backTexture as it is only written to by
219a1e806ed3b2d9e2727d08cc2a3958fce501f6f33Derek Sollenberger    // the consumer thread.
2208ad3ab0e47f0d5039e89c1873c178f538ec1b0dfChris Craik    if (!m_frontTexture)
221afe34397d6d4655c908f0995e760772980722da3Teng-Hui Zhu        return false;
222a5ffb7c279df240a07658953e1bd5df6d0480cb6Nicolas Roard
22332ce41e0241790f20e63cafea4d3c1db87423eecChris Craik    if (fillPortion.x() < 1.0f || fillPortion.y() < 1.0f)
22432ce41e0241790f20e63cafea4d3c1db87423eecChris Craik        ALOGV("drawing tile %p (%d, %d with fill portions %f %f",
22532ce41e0241790f20e63cafea4d3c1db87423eecChris Craik              this, m_x, m_y, fillPortion.x(), fillPortion.y());
22632ce41e0241790f20e63cafea4d3c1db87423eecChris Craik
2273efc67e0caf0b63fe0350d6896d2cbc08661f5d7Teng-Hui Zhu    m_frontTexture->drawGL(isLayerTile(), rect, opacity, transform,
22832ce41e0241790f20e63cafea4d3c1db87423eecChris Craik                           forceBlending, usePointSampling, fillPortion);
229afe34397d6d4655c908f0995e760772980722da3Teng-Hui Zhu    return true;
230a5ffb7c279df240a07658953e1bd5df6d0480cb6Nicolas Roard}
231a5ffb7c279df240a07658953e1bd5df6d0480cb6Nicolas Roard
232594c6b805969c2673c84d1d1d1a3556ce376ac7aChris Craikbool Tile::isTileReady()
233a5ffb7c279df240a07658953e1bd5df6d0480cb6Nicolas Roard{
2348ad3ab0e47f0d5039e89c1873c178f538ec1b0dfChris Craik    // Return true if the tile's most recently drawn texture is up to date
2358ad3ab0e47f0d5039e89c1873c178f538ec1b0dfChris Craik    android::AutoMutex lock(m_atomicSync);
236594c6b805969c2673c84d1d1d1a3556ce376ac7aChris Craik    TileTexture * texture = (m_state == ReadyToSwap) ? m_backTexture : m_frontTexture;
2378ad3ab0e47f0d5039e89c1873c178f538ec1b0dfChris Craik
2388ad3ab0e47f0d5039e89c1873c178f538ec1b0dfChris Craik    if (!texture)
239a5ffb7c279df240a07658953e1bd5df6d0480cb6Nicolas Roard        return false;
2408ad3ab0e47f0d5039e89c1873c178f538ec1b0dfChris Craik
2418ad3ab0e47f0d5039e89c1873c178f538ec1b0dfChris Craik    if (texture->owner() != this)
242a5ffb7c279df240a07658953e1bd5df6d0480cb6Nicolas Roard        return false;
243a1e806ed3b2d9e2727d08cc2a3958fce501f6f33Derek Sollenberger
24467e4aa15702646d5ff50e9524f4e63eb9ed20122Nicolas Roard    if (m_dirty)
24567e4aa15702646d5ff50e9524f4e63eb9ed20122Nicolas Roard        return false;
24667e4aa15702646d5ff50e9524f4e63eb9ed20122Nicolas Roard
247f6a40880028cf495025747229c627f42e25acc66Chris Craik    if (m_state != ReadyToSwap && m_state != UpToDate)
248f6a40880028cf495025747229c627f42e25acc66Chris Craik        return false;
249f6a40880028cf495025747229c627f42e25acc66Chris Craik
250f8f42bbda64a56cfd5ab48a274020d4efc9a5594Chris Craik    return true;
251a5ffb7c279df240a07658953e1bd5df6d0480cb6Nicolas Roard}
252a5ffb7c279df240a07658953e1bd5df6d0480cb6Nicolas Roard
253594c6b805969c2673c84d1d1d1a3556ce376ac7aChris Craikbool Tile::intersectWithRect(int x, int y, int tileWidth, int tileHeight,
254594c6b805969c2673c84d1d1d1a3556ce376ac7aChris Craik                             float scale, const SkRect& dirtyRect,
255594c6b805969c2673c84d1d1d1a3556ce376ac7aChris Craik                             SkRect& realTileRect)
256fa807bd31774157959640810e564fbe64338e8e3Nicolas Roard{
257fa807bd31774157959640810e564fbe64338e8e3Nicolas Roard    // compute the rect to corresponds to pixels
258fa807bd31774157959640810e564fbe64338e8e3Nicolas Roard    realTileRect.fLeft = x * tileWidth;
259fa807bd31774157959640810e564fbe64338e8e3Nicolas Roard    realTileRect.fTop = y * tileHeight;
260fa807bd31774157959640810e564fbe64338e8e3Nicolas Roard    realTileRect.fRight = realTileRect.fLeft + tileWidth;
261fa807bd31774157959640810e564fbe64338e8e3Nicolas Roard    realTileRect.fBottom = realTileRect.fTop + tileHeight;
262fa807bd31774157959640810e564fbe64338e8e3Nicolas Roard
263fa807bd31774157959640810e564fbe64338e8e3Nicolas Roard    // scale the dirtyRect for intersect computation.
264fa807bd31774157959640810e564fbe64338e8e3Nicolas Roard    SkRect realDirtyRect = SkRect::MakeWH(dirtyRect.width() * scale,
265fa807bd31774157959640810e564fbe64338e8e3Nicolas Roard                                          dirtyRect.height() * scale);
266fa807bd31774157959640810e564fbe64338e8e3Nicolas Roard    realDirtyRect.offset(dirtyRect.fLeft * scale, dirtyRect.fTop * scale);
267fa807bd31774157959640810e564fbe64338e8e3Nicolas Roard
268fa807bd31774157959640810e564fbe64338e8e3Nicolas Roard    if (!realTileRect.intersect(realDirtyRect))
269fa807bd31774157959640810e564fbe64338e8e3Nicolas Roard        return false;
270fa807bd31774157959640810e564fbe64338e8e3Nicolas Roard    return true;
271fa807bd31774157959640810e564fbe64338e8e3Nicolas Roard}
272fa807bd31774157959640810e564fbe64338e8e3Nicolas Roard
273594c6b805969c2673c84d1d1d1a3556ce376ac7aChris Craikbool Tile::isTileVisible(const IntRect& viewTileBounds)
274e48d27773894f36d85e5c2e2052ab90d502e1c72Chris Craik{
275e48d27773894f36d85e5c2e2052ab90d502e1c72Chris Craik    return (m_x >= viewTileBounds.x()
276e48d27773894f36d85e5c2e2052ab90d502e1c72Chris Craik            && m_x < viewTileBounds.x() + viewTileBounds.width()
277e48d27773894f36d85e5c2e2052ab90d502e1c72Chris Craik            && m_y >= viewTileBounds.y()
278e48d27773894f36d85e5c2e2052ab90d502e1c72Chris Craik            && m_y < viewTileBounds.y() + viewTileBounds.height());
279e48d27773894f36d85e5c2e2052ab90d502e1c72Chris Craik}
280e48d27773894f36d85e5c2e2052ab90d502e1c72Chris Craik
2813a7a2aa023d51b1806d4063ab0ea5ef7d488556fNicolas Roard// This is called from the texture generation thread
282594c6b805969c2673c84d1d1d1a3556ce376ac7aChris Craikvoid Tile::paintBitmap(TilePainter* painter)
283a5ffb7c279df240a07658953e1bd5df6d0480cb6Nicolas Roard{
284a1e806ed3b2d9e2727d08cc2a3958fce501f6f33Derek Sollenberger    // We acquire the values below atomically. This ensures that we are reading
285a1e806ed3b2d9e2727d08cc2a3958fce501f6f33Derek Sollenberger    // values correctly across cores. Further, once we have these values they
286a1e806ed3b2d9e2727d08cc2a3958fce501f6f33Derek Sollenberger    // can be updated by other threads without consequence.
287a1e806ed3b2d9e2727d08cc2a3958fce501f6f33Derek Sollenberger    m_atomicSync.lock();
288a1e806ed3b2d9e2727d08cc2a3958fce501f6f33Derek Sollenberger    bool dirty = m_dirty;
289594c6b805969c2673c84d1d1d1a3556ce376ac7aChris Craik    TileTexture* texture = m_backTexture;
29062ee9670dd9beeb9a8f21d8737250c081382e2f5Teng-Hui Zhu    SkRegion dirtyArea = m_dirtyArea;
2913a7a2aa023d51b1806d4063ab0ea5ef7d488556fNicolas Roard    float scale = m_scale;
292be61abb47b98988ca94bd839a1e17c3267365dc9Nicolas Roard    const int x = m_x;
293be61abb47b98988ca94bd839a1e17c3267365dc9Nicolas Roard    const int y = m_y;
294cf1ae53e7b2853d1148ecd784379f12dffda9d43Nicolas Roard
2953c131605fca8e29a88fdc4923d86bdc3f40adb2bNicolas Roard    if (!dirty || !texture) {
2963c131605fca8e29a88fdc4923d86bdc3f40adb2bNicolas Roard        m_atomicSync.unlock();
29775394f5ee0aac2337cdff1597b4e686e22c52833Nicolas Roard        return;
2983c131605fca8e29a88fdc4923d86bdc3f40adb2bNicolas Roard    }
299f6a40880028cf495025747229c627f42e25acc66Chris Craik    if (m_state != Unpainted) {
300d487c56b47c747d3e331ee1892e4c0473363afd2Chris Craik        ALOGV("Warning: started painting tile %p, but was at state %d, ft %p bt %p",
301f6a40880028cf495025747229c627f42e25acc66Chris Craik              this, m_state, m_frontTexture, m_backTexture);
302f6a40880028cf495025747229c627f42e25acc66Chris Craik    }
303f6a40880028cf495025747229c627f42e25acc66Chris Craik    m_state = PaintingStarted;
30462ee9670dd9beeb9a8f21d8737250c081382e2f5Teng-Hui Zhu    TextureInfo* textureInfo = texture->getTextureInfo();
3053c131605fca8e29a88fdc4923d86bdc3f40adb2bNicolas Roard    m_atomicSync.unlock();
306a52793c453c1512d0a18d4ae3108a975f998ae45Derek Sollenberger
307a1e806ed3b2d9e2727d08cc2a3958fce501f6f33Derek Sollenberger    // at this point we can safely check the ownership (if the texture got
308594c6b805969c2673c84d1d1d1a3556ce376ac7aChris Craik    // transferred to another Tile under us)
3098ad3ab0e47f0d5039e89c1873c178f538ec1b0dfChris Craik    if (texture->owner() != this) {
31075394f5ee0aac2337cdff1597b4e686e22c52833Nicolas Roard        return;
311a5ffb7c279df240a07658953e1bd5df6d0480cb6Nicolas Roard    }
312a5ffb7c279df240a07658953e1bd5df6d0480cb6Nicolas Roard
313c7e578330aece3c556ef205365c24676687223e2Derek Sollenberger    // swap out the renderer if necessary
314c7e578330aece3c556ef205365c24676687223e2Derek Sollenberger    BaseRenderer::swapRendererIfNeeded(m_renderer);
315232d0b3572d13d9b4fb1211d9d56252a1ede3ed6Derek Sollenberger    // setup the common renderInfo fields;
316232d0b3572d13d9b4fb1211d9d56252a1ede3ed6Derek Sollenberger    TileRenderInfo renderInfo;
317232d0b3572d13d9b4fb1211d9d56252a1ede3ed6Derek Sollenberger    renderInfo.x = x;
318232d0b3572d13d9b4fb1211d9d56252a1ede3ed6Derek Sollenberger    renderInfo.y = y;
319232d0b3572d13d9b4fb1211d9d56252a1ede3ed6Derek Sollenberger    renderInfo.scale = scale;
320232d0b3572d13d9b4fb1211d9d56252a1ede3ed6Derek Sollenberger    renderInfo.tileSize = texture->getSize();
3213c131605fca8e29a88fdc4923d86bdc3f40adb2bNicolas Roard    renderInfo.tilePainter = painter;
3223c131605fca8e29a88fdc4923d86bdc3f40adb2bNicolas Roard    renderInfo.baseTile = this;
323232d0b3572d13d9b4fb1211d9d56252a1ede3ed6Derek Sollenberger    renderInfo.textureInfo = textureInfo;
324232d0b3572d13d9b4fb1211d9d56252a1ede3ed6Derek Sollenberger
325232d0b3572d13d9b4fb1211d9d56252a1ede3ed6Derek Sollenberger    const float tileWidth = renderInfo.tileSize.width();
326232d0b3572d13d9b4fb1211d9d56252a1ede3ed6Derek Sollenberger    const float tileHeight = renderInfo.tileSize.height();
327232d0b3572d13d9b4fb1211d9d56252a1ede3ed6Derek Sollenberger
32867e4aa15702646d5ff50e9524f4e63eb9ed20122Nicolas Roard    SkRegion::Iterator cliperator(dirtyArea);
32967e4aa15702646d5ff50e9524f4e63eb9ed20122Nicolas Roard
33067e4aa15702646d5ff50e9524f4e63eb9ed20122Nicolas Roard    bool fullRepaint = false;
331f85cf343a02e85633e6b68c7f5db3c033b780607Teng-Hui Zhu
33262ee9670dd9beeb9a8f21d8737250c081382e2f5Teng-Hui Zhu    if (m_fullRepaint
333f85cf343a02e85633e6b68c7f5db3c033b780607Teng-Hui Zhu        || textureInfo->m_width != tileWidth
334fa807bd31774157959640810e564fbe64338e8e3Nicolas Roard        || textureInfo->m_height != tileHeight) {
33567e4aa15702646d5ff50e9524f4e63eb9ed20122Nicolas Roard        fullRepaint = true;
336fca6a67b130c1f97d366460af412ec6e6de14834Derek Sollenberger    }
33767e4aa15702646d5ff50e9524f4e63eb9ed20122Nicolas Roard
338c048426c23be795d3bf870e47429167b4157a2d6Nicolas Roard    // For now, only do full repaint
33962ee9670dd9beeb9a8f21d8737250c081382e2f5Teng-Hui Zhu    fullRepaint = true;
3405d77d7f575389ee1f20a394c635928c2e75667c7Nicolas Roard
341c048426c23be795d3bf870e47429167b4157a2d6Nicolas Roard    if (!fullRepaint) {
342c048426c23be795d3bf870e47429167b4157a2d6Nicolas Roard        // compute the partial inval area
343c048426c23be795d3bf870e47429167b4157a2d6Nicolas Roard        SkIRect totalRect;
344c048426c23be795d3bf870e47429167b4157a2d6Nicolas Roard        totalRect.set(0, 0, 0, 0);
345c048426c23be795d3bf870e47429167b4157a2d6Nicolas Roard        float tileSurface = tileWidth * tileHeight;
346c048426c23be795d3bf870e47429167b4157a2d6Nicolas Roard        float tileSurfaceCap = MAX_INVAL_AREA * tileSurface;
347c048426c23be795d3bf870e47429167b4157a2d6Nicolas Roard
348c048426c23be795d3bf870e47429167b4157a2d6Nicolas Roard        // We join all the invals in the same tile for now
349c048426c23be795d3bf870e47429167b4157a2d6Nicolas Roard        while (!fullRepaint && !cliperator.done()) {
350c048426c23be795d3bf870e47429167b4157a2d6Nicolas Roard            SkRect realTileRect;
351c048426c23be795d3bf870e47429167b4157a2d6Nicolas Roard            SkRect dirtyRect;
352c048426c23be795d3bf870e47429167b4157a2d6Nicolas Roard            dirtyRect.set(cliperator.rect());
353c048426c23be795d3bf870e47429167b4157a2d6Nicolas Roard            bool intersect = intersectWithRect(x, y, tileWidth, tileHeight,
354c048426c23be795d3bf870e47429167b4157a2d6Nicolas Roard                                               scale, dirtyRect, realTileRect);
355c048426c23be795d3bf870e47429167b4157a2d6Nicolas Roard            if (intersect) {
356c048426c23be795d3bf870e47429167b4157a2d6Nicolas Roard                // initialize finalRealRect to the rounded values of realTileRect
357c048426c23be795d3bf870e47429167b4157a2d6Nicolas Roard                SkIRect finalRealRect;
358c048426c23be795d3bf870e47429167b4157a2d6Nicolas Roard                realTileRect.roundOut(&finalRealRect);
359c048426c23be795d3bf870e47429167b4157a2d6Nicolas Roard
360c048426c23be795d3bf870e47429167b4157a2d6Nicolas Roard                // stash the int values of the current width and height
361c048426c23be795d3bf870e47429167b4157a2d6Nicolas Roard                const int iWidth = finalRealRect.width();
362c048426c23be795d3bf870e47429167b4157a2d6Nicolas Roard                const int iHeight = finalRealRect.height();
363c048426c23be795d3bf870e47429167b4157a2d6Nicolas Roard
364c048426c23be795d3bf870e47429167b4157a2d6Nicolas Roard                if (iWidth == tileWidth || iHeight == tileHeight) {
365c048426c23be795d3bf870e47429167b4157a2d6Nicolas Roard                    fullRepaint = true;
366c048426c23be795d3bf870e47429167b4157a2d6Nicolas Roard                    break;
367c048426c23be795d3bf870e47429167b4157a2d6Nicolas Roard                }
368c048426c23be795d3bf870e47429167b4157a2d6Nicolas Roard
369c048426c23be795d3bf870e47429167b4157a2d6Nicolas Roard                // translate the rect into tile space coordinates
370c048426c23be795d3bf870e47429167b4157a2d6Nicolas Roard                finalRealRect.fLeft = finalRealRect.fLeft % static_cast<int>(tileWidth);
371c048426c23be795d3bf870e47429167b4157a2d6Nicolas Roard                finalRealRect.fTop = finalRealRect.fTop % static_cast<int>(tileHeight);
372c048426c23be795d3bf870e47429167b4157a2d6Nicolas Roard                finalRealRect.fRight = finalRealRect.fLeft + iWidth;
373c048426c23be795d3bf870e47429167b4157a2d6Nicolas Roard                finalRealRect.fBottom = finalRealRect.fTop + iHeight;
374c048426c23be795d3bf870e47429167b4157a2d6Nicolas Roard                totalRect.join(finalRealRect);
375c048426c23be795d3bf870e47429167b4157a2d6Nicolas Roard                float repaintSurface = totalRect.width() * totalRect.height();
376c048426c23be795d3bf870e47429167b4157a2d6Nicolas Roard
377c048426c23be795d3bf870e47429167b4157a2d6Nicolas Roard                if (repaintSurface > tileSurfaceCap) {
378c048426c23be795d3bf870e47429167b4157a2d6Nicolas Roard                    fullRepaint = true;
379c048426c23be795d3bf870e47429167b4157a2d6Nicolas Roard                    break;
380c048426c23be795d3bf870e47429167b4157a2d6Nicolas Roard                }
381fca6a67b130c1f97d366460af412ec6e6de14834Derek Sollenberger            }
382fca6a67b130c1f97d366460af412ec6e6de14834Derek Sollenberger
383c048426c23be795d3bf870e47429167b4157a2d6Nicolas Roard            cliperator.next();
384c048426c23be795d3bf870e47429167b4157a2d6Nicolas Roard        }
38567e4aa15702646d5ff50e9524f4e63eb9ed20122Nicolas Roard
386c048426c23be795d3bf870e47429167b4157a2d6Nicolas Roard        if (!fullRepaint) {
387c048426c23be795d3bf870e47429167b4157a2d6Nicolas Roard            renderInfo.invalRect = &totalRect;
388f7ad77dc2a981834d664fd24022c3dfade69c8aaChris Craik            m_renderer->renderTiledContent(renderInfo);
38967e4aa15702646d5ff50e9524f4e63eb9ed20122Nicolas Roard        }
39067e4aa15702646d5ff50e9524f4e63eb9ed20122Nicolas Roard    }
391fca6a67b130c1f97d366460af412ec6e6de14834Derek Sollenberger
392fa807bd31774157959640810e564fbe64338e8e3Nicolas Roard    // Do a full repaint if needed
393fca6a67b130c1f97d366460af412ec6e6de14834Derek Sollenberger    if (fullRepaint) {
394c048426c23be795d3bf870e47429167b4157a2d6Nicolas Roard        renderInfo.invalRect = 0;
395f7ad77dc2a981834d664fd24022c3dfade69c8aaChris Craik        m_renderer->renderTiledContent(renderInfo);
396fca6a67b130c1f97d366460af412ec6e6de14834Derek Sollenberger    }
397fca6a67b130c1f97d366460af412ec6e6de14834Derek Sollenberger
39867e4aa15702646d5ff50e9524f4e63eb9ed20122Nicolas Roard    m_atomicSync.lock();
3997c554a61cb935660cdc86905d040c781b490150fTeng-Hui Zhu
4008ad3ab0e47f0d5039e89c1873c178f538ec1b0dfChris Craik    if (texture == m_backTexture) {
4015ba4a087b9212ca9ae083f015637f417199d85ccJohn Reck        // set the fullrepaint flags
40262ee9670dd9beeb9a8f21d8737250c081382e2f5Teng-Hui Zhu        m_fullRepaint = false;
40367e4aa15702646d5ff50e9524f4e63eb9ed20122Nicolas Roard
4045ba4a087b9212ca9ae083f015637f417199d85ccJohn Reck        // The various checks to see if we are still dirty...
40567e4aa15702646d5ff50e9524f4e63eb9ed20122Nicolas Roard
4065ba4a087b9212ca9ae083f015637f417199d85ccJohn Reck        m_dirty = false;
40767e4aa15702646d5ff50e9524f4e63eb9ed20122Nicolas Roard
4085ba4a087b9212ca9ae083f015637f417199d85ccJohn Reck        if (m_scale != scale)
4095ba4a087b9212ca9ae083f015637f417199d85ccJohn Reck            m_dirty = true;
41067e4aa15702646d5ff50e9524f4e63eb9ed20122Nicolas Roard
411fca6a67b130c1f97d366460af412ec6e6de14834Derek Sollenberger        if (fullRepaint)
41262ee9670dd9beeb9a8f21d8737250c081382e2f5Teng-Hui Zhu            m_dirtyArea.setEmpty();
413fca6a67b130c1f97d366460af412ec6e6de14834Derek Sollenberger        else
41462ee9670dd9beeb9a8f21d8737250c081382e2f5Teng-Hui Zhu            m_dirtyArea.op(dirtyArea, SkRegion::kDifference_Op);
41567e4aa15702646d5ff50e9524f4e63eb9ed20122Nicolas Roard
41662ee9670dd9beeb9a8f21d8737250c081382e2f5Teng-Hui Zhu        if (!m_dirtyArea.isEmpty())
4175ba4a087b9212ca9ae083f015637f417199d85ccJohn Reck            m_dirty = true;
418c15781f45f0d19a925be7fd73bd10c318562db70Nicolas Roard
419d487c56b47c747d3e331ee1892e4c0473363afd2Chris Craik        ALOGV("painted tile %p (%d, %d), texture %p, dirty=%d", this, x, y, texture, m_dirty);
420e733717c7b60d2ccfee9c47af4659ffb8e70dd73Chris Craik
421f6a40880028cf495025747229c627f42e25acc66Chris Craik        validatePaint();
422f6a40880028cf495025747229c627f42e25acc66Chris Craik    } else {
423d487c56b47c747d3e331ee1892e4c0473363afd2Chris Craik        ALOGV("tile %p no longer owns texture %p, m_state %d. ft %p bt %p",
424d487c56b47c747d3e331ee1892e4c0473363afd2Chris Craik              this, texture, m_state, m_frontTexture, m_backTexture);
4255ba4a087b9212ca9ae083f015637f417199d85ccJohn Reck    }
42667e4aa15702646d5ff50e9524f4e63eb9ed20122Nicolas Roard
42767e4aa15702646d5ff50e9524f4e63eb9ed20122Nicolas Roard    m_atomicSync.unlock();
42867e4aa15702646d5ff50e9524f4e63eb9ed20122Nicolas Roard}
42967e4aa15702646d5ff50e9524f4e63eb9ed20122Nicolas Roard
430594c6b805969c2673c84d1d1d1a3556ce376ac7aChris Craikvoid Tile::discardTextures() {
4318ad3ab0e47f0d5039e89c1873c178f538ec1b0dfChris Craik    android::AutoMutex lock(m_atomicSync);
432d487c56b47c747d3e331ee1892e4c0473363afd2Chris Craik    ALOGV("%p discarding bt %p, ft %p",
433d487c56b47c747d3e331ee1892e4c0473363afd2Chris Craik          this, m_backTexture, m_frontTexture);
4348ad3ab0e47f0d5039e89c1873c178f538ec1b0dfChris Craik    if (m_frontTexture) {
4358ad3ab0e47f0d5039e89c1873c178f538ec1b0dfChris Craik        m_frontTexture->release(this);
4368ad3ab0e47f0d5039e89c1873c178f538ec1b0dfChris Craik        m_frontTexture = 0;
4378ad3ab0e47f0d5039e89c1873c178f538ec1b0dfChris Craik    }
4388ad3ab0e47f0d5039e89c1873c178f538ec1b0dfChris Craik    if (m_backTexture) {
4398ad3ab0e47f0d5039e89c1873c178f538ec1b0dfChris Craik        m_backTexture->release(this);
4408ad3ab0e47f0d5039e89c1873c178f538ec1b0dfChris Craik        m_backTexture = 0;
4418ad3ab0e47f0d5039e89c1873c178f538ec1b0dfChris Craik    }
44262ee9670dd9beeb9a8f21d8737250c081382e2f5Teng-Hui Zhu    m_dirtyArea.setEmpty();
44362ee9670dd9beeb9a8f21d8737250c081382e2f5Teng-Hui Zhu    m_fullRepaint = true;
44462ee9670dd9beeb9a8f21d8737250c081382e2f5Teng-Hui Zhu
4458ad3ab0e47f0d5039e89c1873c178f538ec1b0dfChris Craik    m_dirty = true;
446f6a40880028cf495025747229c627f42e25acc66Chris Craik    m_state = Unpainted;
4478ad3ab0e47f0d5039e89c1873c178f538ec1b0dfChris Craik}
4488ad3ab0e47f0d5039e89c1873c178f538ec1b0dfChris Craik
449594c6b805969c2673c84d1d1d1a3556ce376ac7aChris Craikvoid Tile::discardBackTexture() {
4503a819aac70dd26f675644f6a35b13be5fb3de2f1Chris Craik    android::AutoMutex lock(m_atomicSync);
4513a819aac70dd26f675644f6a35b13be5fb3de2f1Chris Craik    if (m_backTexture) {
4523a819aac70dd26f675644f6a35b13be5fb3de2f1Chris Craik        m_backTexture->release(this);
4533a819aac70dd26f675644f6a35b13be5fb3de2f1Chris Craik        m_backTexture = 0;
4543a819aac70dd26f675644f6a35b13be5fb3de2f1Chris Craik    }
4553ef9d5cc655b8274860b8d15441201d3e621baf5Chris Craik    m_state = Unpainted;
4563ef9d5cc655b8274860b8d15441201d3e621baf5Chris Craik    m_dirty = true;
4573a819aac70dd26f675644f6a35b13be5fb3de2f1Chris Craik}
4583a819aac70dd26f675644f6a35b13be5fb3de2f1Chris Craik
459594c6b805969c2673c84d1d1d1a3556ce376ac7aChris Craikbool Tile::swapTexturesIfNeeded() {
4608ad3ab0e47f0d5039e89c1873c178f538ec1b0dfChris Craik    android::AutoMutex lock(m_atomicSync);
461f6a40880028cf495025747229c627f42e25acc66Chris Craik    if (m_state == ReadyToSwap) {
4628ad3ab0e47f0d5039e89c1873c178f538ec1b0dfChris Craik        // discard old texture and swap the new one in its place
4638ad3ab0e47f0d5039e89c1873c178f538ec1b0dfChris Craik        if (m_frontTexture)
4648ad3ab0e47f0d5039e89c1873c178f538ec1b0dfChris Craik            m_frontTexture->release(this);
4658ad3ab0e47f0d5039e89c1873c178f538ec1b0dfChris Craik
4668ad3ab0e47f0d5039e89c1873c178f538ec1b0dfChris Craik        m_frontTexture = m_backTexture;
4678ad3ab0e47f0d5039e89c1873c178f538ec1b0dfChris Craik        m_backTexture = 0;
468f6a40880028cf495025747229c627f42e25acc66Chris Craik        m_state = UpToDate;
469d487c56b47c747d3e331ee1892e4c0473363afd2Chris Craik        ALOGV("display texture for %p at %d, %d front is now %p, back is %p",
470d487c56b47c747d3e331ee1892e4c0473363afd2Chris Craik              this, m_x, m_y, m_frontTexture, m_backTexture);
471f6a40880028cf495025747229c627f42e25acc66Chris Craik
4728ad3ab0e47f0d5039e89c1873c178f538ec1b0dfChris Craik        return true;
4738ad3ab0e47f0d5039e89c1873c178f538ec1b0dfChris Craik    }
4748ad3ab0e47f0d5039e89c1873c178f538ec1b0dfChris Craik    return false;
4758ad3ab0e47f0d5039e89c1873c178f538ec1b0dfChris Craik}
4768ad3ab0e47f0d5039e89c1873c178f538ec1b0dfChris Craik
477594c6b805969c2673c84d1d1d1a3556ce376ac7aChris Craikvoid Tile::backTextureTransfer() {
478f6a40880028cf495025747229c627f42e25acc66Chris Craik    android::AutoMutex lock(m_atomicSync);
479f6a40880028cf495025747229c627f42e25acc66Chris Craik    if (m_state == PaintingStarted)
480f6a40880028cf495025747229c627f42e25acc66Chris Craik        m_state = TransferredUnvalidated;
481f6a40880028cf495025747229c627f42e25acc66Chris Craik    else if (m_state == ValidatedUntransferred)
482f6a40880028cf495025747229c627f42e25acc66Chris Craik        m_state = ReadyToSwap;
483f6a40880028cf495025747229c627f42e25acc66Chris Craik    else {
484f6a40880028cf495025747229c627f42e25acc66Chris Craik        // shouldn't have transferred a tile in any other state, log
485d487c56b47c747d3e331ee1892e4c0473363afd2Chris Craik        ALOGV("Note: transferred tile %p at %d %d, state wasn't paintingstarted or validated: %d",
486d487c56b47c747d3e331ee1892e4c0473363afd2Chris Craik              this, m_x, m_y, m_state);
487f6a40880028cf495025747229c627f42e25acc66Chris Craik    }
488f6a40880028cf495025747229c627f42e25acc66Chris Craik}
489f6a40880028cf495025747229c627f42e25acc66Chris Craik
490594c6b805969c2673c84d1d1d1a3556ce376ac7aChris Craikvoid Tile::backTextureTransferFail() {
491530c83c6351e05a6939ad0b5bc291da073e77b5bChris Craik    // transfer failed for some reason, mark dirty so it will (repaint and) be
492530c83c6351e05a6939ad0b5bc291da073e77b5bChris Craik    // retransferred.
493530c83c6351e05a6939ad0b5bc291da073e77b5bChris Craik    android::AutoMutex lock(m_atomicSync);
494530c83c6351e05a6939ad0b5bc291da073e77b5bChris Craik    m_state = Unpainted;
4953ef9d5cc655b8274860b8d15441201d3e621baf5Chris Craik    m_dirty = true;
496530c83c6351e05a6939ad0b5bc291da073e77b5bChris Craik    // whether validatePaint is called before or after, it won't do anything
497530c83c6351e05a6939ad0b5bc291da073e77b5bChris Craik}
498530c83c6351e05a6939ad0b5bc291da073e77b5bChris Craik
499594c6b805969c2673c84d1d1d1a3556ce376ac7aChris Craikvoid Tile::validatePaint() {
500f6a40880028cf495025747229c627f42e25acc66Chris Craik    // ONLY CALL while m_atomicSync is locked (at the end of paintBitmap())
501f6a40880028cf495025747229c627f42e25acc66Chris Craik
502f6a40880028cf495025747229c627f42e25acc66Chris Craik    if (!m_dirty) {
503f6a40880028cf495025747229c627f42e25acc66Chris Craik        // since after the paint, the tile isn't dirty, 'validate' it - this
504f6a40880028cf495025747229c627f42e25acc66Chris Craik        // may happed before or after the transfer queue operation. Only
505f6a40880028cf495025747229c627f42e25acc66Chris Craik        // when both have happened, mark as 'ReadyToSwap'
506f6a40880028cf495025747229c627f42e25acc66Chris Craik        if (m_state == PaintingStarted)
507f6a40880028cf495025747229c627f42e25acc66Chris Craik            m_state = ValidatedUntransferred;
508309ae897e0ad3493fc6acd97a39c631f90580d57Teng-Hui Zhu        else if (m_state == TransferredUnvalidated) {
5098abedfb0681eb18f62137fffde000a9dbb75c4d2Teng-Hui Zhu            // When the backTexture has been marked pureColor, we will skip the
5108abedfb0681eb18f62137fffde000a9dbb75c4d2Teng-Hui Zhu            // transfer and marked as ReadyToSwap, in this case, we don't want
5118abedfb0681eb18f62137fffde000a9dbb75c4d2Teng-Hui Zhu            // to reset m_dirty bit to true.
512f6a40880028cf495025747229c627f42e25acc66Chris Craik            m_state = ReadyToSwap;
5138abedfb0681eb18f62137fffde000a9dbb75c4d2Teng-Hui Zhu        } else {
514d487c56b47c747d3e331ee1892e4c0473363afd2Chris Craik            ALOGV("Note: validated tile %p at %d %d, state wasn't paintingstarted or transferred %d",
515f6a40880028cf495025747229c627f42e25acc66Chris Craik                  this, m_x, m_y, m_state);
5163ef9d5cc655b8274860b8d15441201d3e621baf5Chris Craik            // failed transferring, in which case mark dirty (since
5173ef9d5cc655b8274860b8d15441201d3e621baf5Chris Craik            // paintBitmap() may have cleared m_dirty)
5183ef9d5cc655b8274860b8d15441201d3e621baf5Chris Craik            m_dirty = true;
519f6a40880028cf495025747229c627f42e25acc66Chris Craik        }
520f6a40880028cf495025747229c627f42e25acc66Chris Craik    } else {
521d487c56b47c747d3e331ee1892e4c0473363afd2Chris Craik        ALOGV("Note: paint was unsuccessful.");
522f6a40880028cf495025747229c627f42e25acc66Chris Craik        m_state = Unpainted;
523f6a40880028cf495025747229c627f42e25acc66Chris Craik    }
524f6a40880028cf495025747229c627f42e25acc66Chris Craik
525f6a40880028cf495025747229c627f42e25acc66Chris Craik}
526f6a40880028cf495025747229c627f42e25acc66Chris Craik
527a5ffb7c279df240a07658953e1bd5df6d0480cb6Nicolas Roard} // namespace WebCore
528a5ffb7c279df240a07658953e1bd5df6d0480cb6Nicolas Roard
529a5ffb7c279df240a07658953e1bd5df6d0480cb6Nicolas Roard#endif // USE(ACCELERATED_COMPOSITING)
530