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)
550c274b96c2dfb5a83b12a99f1ca9069378f73bdbChris Craik    , m_lastDrawnTexture(0)
56a5ffb7c279df240a07658953e1bd5df6d0480cb6Nicolas Roard    , m_scale(1)
57a1e806ed3b2d9e2727d08cc2a3958fce501f6f33Derek Sollenberger    , m_dirty(true)
5855ff9f5ac537f2b11ae997f1029bdccb87008825Chris Craik    , m_repaintsPending(0)
5962ee9670dd9beeb9a8f21d8737250c081382e2f5Teng-Hui Zhu    , m_fullRepaint(true)
603c131605fca8e29a88fdc4923d86bdc3f40adb2bNicolas Roard    , m_isLayerTile(isLayerTile)
618ad3ab0e47f0d5039e89c1873c178f538ec1b0dfChris Craik    , m_drawCount(0)
62f6a40880028cf495025747229c627f42e25acc66Chris Craik    , m_state(Unpainted)
63a5ffb7c279df240a07658953e1bd5df6d0480cb6Nicolas Roard{
64a5ffb7c279df240a07658953e1bd5df6d0480cb6Nicolas Roard#ifdef DEBUG_COUNT
65594c6b805969c2673c84d1d1d1a3556ce376ac7aChris Craik    ClassTracker::instance()->increment("Tile");
66a5ffb7c279df240a07658953e1bd5df6d0480cb6Nicolas Roard#endif
67c7e578330aece3c556ef205365c24676687223e2Derek Sollenberger    m_renderer = BaseRenderer::createRenderer();
68a5ffb7c279df240a07658953e1bd5df6d0480cb6Nicolas Roard}
69a5ffb7c279df240a07658953e1bd5df6d0480cb6Nicolas Roard
70594c6b805969c2673c84d1d1d1a3556ce376ac7aChris CraikTile::~Tile()
71a5ffb7c279df240a07658953e1bd5df6d0480cb6Nicolas Roard{
728ad3ab0e47f0d5039e89c1873c178f538ec1b0dfChris Craik    if (m_backTexture)
738ad3ab0e47f0d5039e89c1873c178f538ec1b0dfChris Craik        m_backTexture->release(this);
748ad3ab0e47f0d5039e89c1873c178f538ec1b0dfChris Craik    if (m_frontTexture)
758ad3ab0e47f0d5039e89c1873c178f538ec1b0dfChris Craik        m_frontTexture->release(this);
7690455eb70cca2df540942299b35bb3bd8261cb0bDerek Sollenberger
778dfdf8aa25b250ed3b8c0a443cf1cbaf9bd12c5bDerek Sollenberger    delete m_renderer;
788dfdf8aa25b250ed3b8c0a443cf1cbaf9bd12c5bDerek Sollenberger
79a5ffb7c279df240a07658953e1bd5df6d0480cb6Nicolas Roard#ifdef DEBUG_COUNT
80594c6b805969c2673c84d1d1d1a3556ce376ac7aChris Craik    ClassTracker::instance()->decrement("Tile");
81a5ffb7c279df240a07658953e1bd5df6d0480cb6Nicolas Roard#endif
82a5ffb7c279df240a07658953e1bd5df6d0480cb6Nicolas Roard}
83a5ffb7c279df240a07658953e1bd5df6d0480cb6Nicolas Roard
843a7a2aa023d51b1806d4063ab0ea5ef7d488556fNicolas Roard// All the following functions must be called from the main GL thread.
853a7a2aa023d51b1806d4063ab0ea5ef7d488556fNicolas Roard
86594c6b805969c2673c84d1d1d1a3556ce376ac7aChris Craikvoid Tile::setContents(int x, int y, float scale, bool isExpandedPrefetchTile)
87ffc715a2e6382fe9e331557c35fafc426507b8f5Derek Sollenberger{
88d8be9016b7fda67a91b4ee17b3b2e7ba692ee553Chris Craik    // TODO: investigate whether below check/discard is necessary
8992db4f76a7eca8f91084ec2eedde77b161786f23Chris Craik    if ((m_x != x)
903c131605fca8e29a88fdc4923d86bdc3f40adb2bNicolas Roard        || (m_y != y)
91f6a40880028cf495025747229c627f42e25acc66Chris Craik        || (m_scale != scale)) {
92f6a40880028cf495025747229c627f42e25acc66Chris Craik        // neither texture is relevant
93f6a40880028cf495025747229c627f42e25acc66Chris Craik        discardTextures();
94f6a40880028cf495025747229c627f42e25acc66Chris Craik    }
953c131605fca8e29a88fdc4923d86bdc3f40adb2bNicolas Roard
96f6a40880028cf495025747229c627f42e25acc66Chris Craik    android::AutoMutex lock(m_atomicSync);
97ffc715a2e6382fe9e331557c35fafc426507b8f5Derek Sollenberger    m_x = x;
98ffc715a2e6382fe9e331557c35fafc426507b8f5Derek Sollenberger    m_y = y;
993c131605fca8e29a88fdc4923d86bdc3f40adb2bNicolas Roard    m_scale = scale;
1008ad3ab0e47f0d5039e89c1873c178f538ec1b0dfChris Craik    m_drawCount = TilesManager::instance()->getDrawGLCount();
101c51715092b8d3be1b51cce8bae61750cbcf342c4Chris Craik    if (isExpandedPrefetchTile)
102c51715092b8d3be1b51cce8bae61750cbcf342c4Chris Craik        m_drawCount--; // deprioritize expanded painting region
103ffc715a2e6382fe9e331557c35fafc426507b8f5Derek Sollenberger}
104ffc715a2e6382fe9e331557c35fafc426507b8f5Derek Sollenberger
105594c6b805969c2673c84d1d1d1a3556ce376ac7aChris Craikvoid Tile::reserveTexture()
106a5ffb7c279df240a07658953e1bd5df6d0480cb6Nicolas Roard{
107594c6b805969c2673c84d1d1d1a3556ce376ac7aChris Craik    TileTexture* texture = TilesManager::instance()->getAvailableTexture(this);
108a1e806ed3b2d9e2727d08cc2a3958fce501f6f33Derek Sollenberger
109a1e806ed3b2d9e2727d08cc2a3958fce501f6f33Derek Sollenberger    android::AutoMutex lock(m_atomicSync);
1108ad3ab0e47f0d5039e89c1873c178f538ec1b0dfChris Craik    if (texture && m_backTexture != texture) {
111d487c56b47c747d3e331ee1892e4c0473363afd2Chris Craik        ALOGV("tile %p reserving texture %p, back was %p (front %p)",
112d487c56b47c747d3e331ee1892e4c0473363afd2Chris Craik              this, texture, m_backTexture, m_frontTexture);
113f6a40880028cf495025747229c627f42e25acc66Chris Craik        m_state = Unpainted;
1148ad3ab0e47f0d5039e89c1873c178f538ec1b0dfChris Craik        m_backTexture = texture;
115a1e806ed3b2d9e2727d08cc2a3958fce501f6f33Derek Sollenberger    }
1166aa089bded6a1abbf8d61264588e1e3a32be31b3Chris Craik
117f6a40880028cf495025747229c627f42e25acc66Chris Craik    if (m_state == UpToDate) {
118d487c56b47c747d3e331ee1892e4c0473363afd2Chris Craik        ALOGV("moving tile %p to unpainted, since it reserved while up to date", this);
1196aa089bded6a1abbf8d61264588e1e3a32be31b3Chris Craik        m_dirty = true;
120f6a40880028cf495025747229c627f42e25acc66Chris Craik        m_state = Unpainted;
121f6a40880028cf495025747229c627f42e25acc66Chris Craik    }
122a5ffb7c279df240a07658953e1bd5df6d0480cb6Nicolas Roard}
123a5ffb7c279df240a07658953e1bd5df6d0480cb6Nicolas Roard
124594c6b805969c2673c84d1d1d1a3556ce376ac7aChris Craikbool Tile::removeTexture(TileTexture* texture)
125a5ffb7c279df240a07658953e1bd5df6d0480cb6Nicolas Roard{
1267b4a179bde698a856bed54a680438a9db3ff0566Chris Craik    ALOGV("%p removeTexture %p, back %p front %p",
1277b4a179bde698a856bed54a680438a9db3ff0566Chris Craik          this, texture, m_backTexture, m_frontTexture);
1283a7a2aa023d51b1806d4063ab0ea5ef7d488556fNicolas Roard    // We update atomically, so paintBitmap() can see the correct value
129a1e806ed3b2d9e2727d08cc2a3958fce501f6f33Derek Sollenberger    android::AutoMutex lock(m_atomicSync);
130f6a40880028cf495025747229c627f42e25acc66Chris Craik    if (m_frontTexture == texture) {
131f6a40880028cf495025747229c627f42e25acc66Chris Craik        if (m_state == UpToDate) {
132d487c56b47c747d3e331ee1892e4c0473363afd2Chris Craik            ALOGV("front texture removed, state was UpToDate, now becoming unpainted, bt is %p", m_backTexture);
133f6a40880028cf495025747229c627f42e25acc66Chris Craik            m_state = Unpainted;
134f6a40880028cf495025747229c627f42e25acc66Chris Craik        }
135f6a40880028cf495025747229c627f42e25acc66Chris Craik
1368ad3ab0e47f0d5039e89c1873c178f538ec1b0dfChris Craik        m_frontTexture = 0;
137f6a40880028cf495025747229c627f42e25acc66Chris Craik    }
138f6a40880028cf495025747229c627f42e25acc66Chris Craik    if (m_backTexture == texture) {
139f6a40880028cf495025747229c627f42e25acc66Chris Craik        m_state = Unpainted;
1408ad3ab0e47f0d5039e89c1873c178f538ec1b0dfChris Craik        m_backTexture = 0;
141f6a40880028cf495025747229c627f42e25acc66Chris Craik    }
1426aa089bded6a1abbf8d61264588e1e3a32be31b3Chris Craik
1436aa089bded6a1abbf8d61264588e1e3a32be31b3Chris Craik    // mark dirty regardless of which texture was taken - the back texture may
1446aa089bded6a1abbf8d61264588e1e3a32be31b3Chris Craik    // have been ready to swap
1456aa089bded6a1abbf8d61264588e1e3a32be31b3Chris Craik    m_dirty = true;
1466aa089bded6a1abbf8d61264588e1e3a32be31b3Chris Craik
14781ec1fafcb2c1bc433ec34b6ae4ea78d1ea7d3a8Nicolas Roard    return true;
1483a7a2aa023d51b1806d4063ab0ea5ef7d488556fNicolas Roard}
1493a7a2aa023d51b1806d4063ab0ea5ef7d488556fNicolas Roard
150bd3f93b66934582acd0b6c70bcf60ca643b36eadChris Craikvoid Tile::markAsDirty()
151bd3f93b66934582acd0b6c70bcf60ca643b36eadChris Craik{
152bd3f93b66934582acd0b6c70bcf60ca643b36eadChris Craik    android::AutoMutex lock(m_atomicSync);
153bd3f93b66934582acd0b6c70bcf60ca643b36eadChris Craik    m_dirtyArea.setEmpty(); // empty dirty rect prevents fast blit path
154bd3f93b66934582acd0b6c70bcf60ca643b36eadChris Craik    markAsDirtyInternal();
155bd3f93b66934582acd0b6c70bcf60ca643b36eadChris Craik}
156bd3f93b66934582acd0b6c70bcf60ca643b36eadChris Craik
157594c6b805969c2673c84d1d1d1a3556ce376ac7aChris Craikvoid Tile::markAsDirty(const SkRegion& dirtyArea)
158a1e806ed3b2d9e2727d08cc2a3958fce501f6f33Derek Sollenberger{
159fa807bd31774157959640810e564fbe64338e8e3Nicolas Roard    if (dirtyArea.isEmpty())
160fa807bd31774157959640810e564fbe64338e8e3Nicolas Roard        return;
161a1e806ed3b2d9e2727d08cc2a3958fce501f6f33Derek Sollenberger    android::AutoMutex lock(m_atomicSync);
16262ee9670dd9beeb9a8f21d8737250c081382e2f5Teng-Hui Zhu    m_dirtyArea.op(dirtyArea, SkRegion::kUnion_Op);
16361a908361c8a96eeb70afdb5430e89845edb2bddNicolas Roard
16461a908361c8a96eeb70afdb5430e89845edb2bddNicolas Roard    // Check if we actually intersect with the area
16561a908361c8a96eeb70afdb5430e89845edb2bddNicolas Roard    bool intersect = false;
16661a908361c8a96eeb70afdb5430e89845edb2bddNicolas Roard    SkRegion::Iterator cliperator(dirtyArea);
16761a908361c8a96eeb70afdb5430e89845edb2bddNicolas Roard    SkRect realTileRect;
16861a908361c8a96eeb70afdb5430e89845edb2bddNicolas Roard    SkRect dirtyRect;
16961a908361c8a96eeb70afdb5430e89845edb2bddNicolas Roard    while (!cliperator.done()) {
17061a908361c8a96eeb70afdb5430e89845edb2bddNicolas Roard        dirtyRect.set(cliperator.rect());
171c51715092b8d3be1b51cce8bae61750cbcf342c4Chris Craik        if (intersectWithRect(m_x, m_y, TilesManager::tileWidth(), TilesManager::tileHeight(),
17261a908361c8a96eeb70afdb5430e89845edb2bddNicolas Roard                              m_scale, dirtyRect, realTileRect)) {
17361a908361c8a96eeb70afdb5430e89845edb2bddNicolas Roard            intersect = true;
17461a908361c8a96eeb70afdb5430e89845edb2bddNicolas Roard            break;
17561a908361c8a96eeb70afdb5430e89845edb2bddNicolas Roard        }
17661a908361c8a96eeb70afdb5430e89845edb2bddNicolas Roard        cliperator.next();
17761a908361c8a96eeb70afdb5430e89845edb2bddNicolas Roard    }
17808c253c5d2dad921120c3e1ab7bc6781064ca31bNicolas Roard
17961a908361c8a96eeb70afdb5430e89845edb2bddNicolas Roard    if (!intersect)
18061a908361c8a96eeb70afdb5430e89845edb2bddNicolas Roard        return;
18161a908361c8a96eeb70afdb5430e89845edb2bddNicolas Roard
182bd3f93b66934582acd0b6c70bcf60ca643b36eadChris Craik    markAsDirtyInternal();
183bd3f93b66934582acd0b6c70bcf60ca643b36eadChris Craik}
184bd3f93b66934582acd0b6c70bcf60ca643b36eadChris Craik
185bd3f93b66934582acd0b6c70bcf60ca643b36eadChris Craikvoid Tile::markAsDirtyInternal()
186bd3f93b66934582acd0b6c70bcf60ca643b36eadChris Craik{
187bd3f93b66934582acd0b6c70bcf60ca643b36eadChris Craik    // NOTE: callers must hold lock on m_atomicSync
188bd3f93b66934582acd0b6c70bcf60ca643b36eadChris Craik
18967e4aa15702646d5ff50e9524f4e63eb9ed20122Nicolas Roard    m_dirty = true;
190f6a40880028cf495025747229c627f42e25acc66Chris Craik    if (m_state == UpToDate) {
191f6a40880028cf495025747229c627f42e25acc66Chris Craik        // We only mark a tile as unpainted in 'markAsDirty' if its status is
192f6a40880028cf495025747229c627f42e25acc66Chris Craik        // UpToDate: marking dirty means we need to repaint, but don't stop the
193f6a40880028cf495025747229c627f42e25acc66Chris Craik        // current paint
194f6a40880028cf495025747229c627f42e25acc66Chris Craik        m_state = Unpainted;
195f6a40880028cf495025747229c627f42e25acc66Chris Craik    } else if (m_state != Unpainted) {
196f6a40880028cf495025747229c627f42e25acc66Chris Craik        // TODO: fix it so that they can paint while deferring the markAsDirty
197f6a40880028cf495025747229c627f42e25acc66Chris Craik        // call (or block updates)
1987b4a179bde698a856bed54a680438a9db3ff0566Chris Craik        ALOGV("Warning: tried to mark tile %p at %d, %d islayertile %d as dirty, state %d",
1997b4a179bde698a856bed54a680438a9db3ff0566Chris Craik              this, m_x, m_y, isLayerTile(), m_state);
200458b4b11924c3bcc70dcdd3d69f64a855870e72dChris Craik
201458b4b11924c3bcc70dcdd3d69f64a855870e72dChris Craik        // prefetch tiles can be marked dirty while in the process of painting,
202458b4b11924c3bcc70dcdd3d69f64a855870e72dChris Craik        // due to not using an update lock. force them to fail validate step.
203458b4b11924c3bcc70dcdd3d69f64a855870e72dChris Craik        m_state = Unpainted;
204f6a40880028cf495025747229c627f42e25acc66Chris Craik    }
205a1e806ed3b2d9e2727d08cc2a3958fce501f6f33Derek Sollenberger}
206a1e806ed3b2d9e2727d08cc2a3958fce501f6f33Derek Sollenberger
207594c6b805969c2673c84d1d1d1a3556ce376ac7aChris Craikbool Tile::isDirty()
208a1e806ed3b2d9e2727d08cc2a3958fce501f6f33Derek Sollenberger{
209a1e806ed3b2d9e2727d08cc2a3958fce501f6f33Derek Sollenberger    android::AutoMutex lock(m_atomicSync);
210a1e806ed3b2d9e2727d08cc2a3958fce501f6f33Derek Sollenberger    return m_dirty;
211a5ffb7c279df240a07658953e1bd5df6d0480cb6Nicolas Roard}
212a5ffb7c279df240a07658953e1bd5df6d0480cb6Nicolas Roard
213594c6b805969c2673c84d1d1d1a3556ce376ac7aChris Craikbool Tile::isRepaintPending()
214417789b7c56928a5fcb610583346d07ffa380900John Reck{
215417789b7c56928a5fcb610583346d07ffa380900John Reck    android::AutoMutex lock(m_atomicSync);
21655ff9f5ac537f2b11ae997f1029bdccb87008825Chris Craik    return m_repaintsPending != 0;
217417789b7c56928a5fcb610583346d07ffa380900John Reck}
218417789b7c56928a5fcb610583346d07ffa380900John Reck
219594c6b805969c2673c84d1d1d1a3556ce376ac7aChris Craikvoid Tile::setRepaintPending(bool pending)
220417789b7c56928a5fcb610583346d07ffa380900John Reck{
221417789b7c56928a5fcb610583346d07ffa380900John Reck    android::AutoMutex lock(m_atomicSync);
22255ff9f5ac537f2b11ae997f1029bdccb87008825Chris Craik    m_repaintsPending += pending ? 1 : -1;
223417789b7c56928a5fcb610583346d07ffa380900John Reck}
224417789b7c56928a5fcb610583346d07ffa380900John Reck
225594c6b805969c2673c84d1d1d1a3556ce376ac7aChris Craikbool Tile::drawGL(float opacity, const SkRect& rect, float scale,
226a31d28d03260660f592ad6914f5375b47e823aa5Teng-Hui Zhu                  const TransformationMatrix* transform,
22732ce41e0241790f20e63cafea4d3c1db87423eecChris Craik                  bool forceBlending, bool usePointSampling,
228485445e9a624fe92ca04a1d0e92c1f71aaf8cd8fTeng-Hui Zhu                  const FloatRect& fillPortion)
229a5ffb7c279df240a07658953e1bd5df6d0480cb6Nicolas Roard{
2301deed5ff76dad5d0783c0e07639338f1d6b08a67Nicolas Roard    if (m_x < 0 || m_y < 0 || m_scale != scale)
231afe34397d6d4655c908f0995e760772980722da3Teng-Hui Zhu        return false;
23267e4aa15702646d5ff50e9524f4e63eb9ed20122Nicolas Roard
2338ad3ab0e47f0d5039e89c1873c178f538ec1b0dfChris Craik    // No need to mutex protect reads of m_backTexture as it is only written to by
234a1e806ed3b2d9e2727d08cc2a3958fce501f6f33Derek Sollenberger    // the consumer thread.
2358ad3ab0e47f0d5039e89c1873c178f538ec1b0dfChris Craik    if (!m_frontTexture)
236afe34397d6d4655c908f0995e760772980722da3Teng-Hui Zhu        return false;
237a5ffb7c279df240a07658953e1bd5df6d0480cb6Nicolas Roard
238485445e9a624fe92ca04a1d0e92c1f71aaf8cd8fTeng-Hui Zhu    if (fillPortion.maxX() < 1.0f || fillPortion.maxY() < 1.0f
239485445e9a624fe92ca04a1d0e92c1f71aaf8cd8fTeng-Hui Zhu        || fillPortion.x() > 0.0f || fillPortion.y() > 0.0f)
240485445e9a624fe92ca04a1d0e92c1f71aaf8cd8fTeng-Hui Zhu        ALOGV("drawing tile %p (%d, %d with fill portions %f %f->%f, %f",
241485445e9a624fe92ca04a1d0e92c1f71aaf8cd8fTeng-Hui Zhu              this, m_x, m_y, fillPortion.x(), fillPortion.y(),
242485445e9a624fe92ca04a1d0e92c1f71aaf8cd8fTeng-Hui Zhu              fillPortion.maxX(), fillPortion.maxY());
24332ce41e0241790f20e63cafea4d3c1db87423eecChris Craik
2443efc67e0caf0b63fe0350d6896d2cbc08661f5d7Teng-Hui Zhu    m_frontTexture->drawGL(isLayerTile(), rect, opacity, transform,
24532ce41e0241790f20e63cafea4d3c1db87423eecChris Craik                           forceBlending, usePointSampling, fillPortion);
2460c274b96c2dfb5a83b12a99f1ca9069378f73bdbChris Craik    m_lastDrawnTexture = m_frontTexture;
247afe34397d6d4655c908f0995e760772980722da3Teng-Hui Zhu    return true;
248a5ffb7c279df240a07658953e1bd5df6d0480cb6Nicolas Roard}
249a5ffb7c279df240a07658953e1bd5df6d0480cb6Nicolas Roard
250594c6b805969c2673c84d1d1d1a3556ce376ac7aChris Craikbool Tile::isTileReady()
251a5ffb7c279df240a07658953e1bd5df6d0480cb6Nicolas Roard{
2528ad3ab0e47f0d5039e89c1873c178f538ec1b0dfChris Craik    // Return true if the tile's most recently drawn texture is up to date
2538ad3ab0e47f0d5039e89c1873c178f538ec1b0dfChris Craik    android::AutoMutex lock(m_atomicSync);
254594c6b805969c2673c84d1d1d1a3556ce376ac7aChris Craik    TileTexture * texture = (m_state == ReadyToSwap) ? m_backTexture : m_frontTexture;
2558ad3ab0e47f0d5039e89c1873c178f538ec1b0dfChris Craik
2568ad3ab0e47f0d5039e89c1873c178f538ec1b0dfChris Craik    if (!texture)
257a5ffb7c279df240a07658953e1bd5df6d0480cb6Nicolas Roard        return false;
2588ad3ab0e47f0d5039e89c1873c178f538ec1b0dfChris Craik
2598ad3ab0e47f0d5039e89c1873c178f538ec1b0dfChris Craik    if (texture->owner() != this)
260a5ffb7c279df240a07658953e1bd5df6d0480cb6Nicolas Roard        return false;
261a1e806ed3b2d9e2727d08cc2a3958fce501f6f33Derek Sollenberger
26267e4aa15702646d5ff50e9524f4e63eb9ed20122Nicolas Roard    if (m_dirty)
26367e4aa15702646d5ff50e9524f4e63eb9ed20122Nicolas Roard        return false;
26467e4aa15702646d5ff50e9524f4e63eb9ed20122Nicolas Roard
265f6a40880028cf495025747229c627f42e25acc66Chris Craik    if (m_state != ReadyToSwap && m_state != UpToDate)
266f6a40880028cf495025747229c627f42e25acc66Chris Craik        return false;
267f6a40880028cf495025747229c627f42e25acc66Chris Craik
268f8f42bbda64a56cfd5ab48a274020d4efc9a5594Chris Craik    return true;
269a5ffb7c279df240a07658953e1bd5df6d0480cb6Nicolas Roard}
270a5ffb7c279df240a07658953e1bd5df6d0480cb6Nicolas Roard
271594c6b805969c2673c84d1d1d1a3556ce376ac7aChris Craikbool Tile::intersectWithRect(int x, int y, int tileWidth, int tileHeight,
272594c6b805969c2673c84d1d1d1a3556ce376ac7aChris Craik                             float scale, const SkRect& dirtyRect,
273594c6b805969c2673c84d1d1d1a3556ce376ac7aChris Craik                             SkRect& realTileRect)
274fa807bd31774157959640810e564fbe64338e8e3Nicolas Roard{
275fa807bd31774157959640810e564fbe64338e8e3Nicolas Roard    // compute the rect to corresponds to pixels
276fa807bd31774157959640810e564fbe64338e8e3Nicolas Roard    realTileRect.fLeft = x * tileWidth;
277fa807bd31774157959640810e564fbe64338e8e3Nicolas Roard    realTileRect.fTop = y * tileHeight;
278fa807bd31774157959640810e564fbe64338e8e3Nicolas Roard    realTileRect.fRight = realTileRect.fLeft + tileWidth;
279fa807bd31774157959640810e564fbe64338e8e3Nicolas Roard    realTileRect.fBottom = realTileRect.fTop + tileHeight;
280fa807bd31774157959640810e564fbe64338e8e3Nicolas Roard
281fa807bd31774157959640810e564fbe64338e8e3Nicolas Roard    // scale the dirtyRect for intersect computation.
282fa807bd31774157959640810e564fbe64338e8e3Nicolas Roard    SkRect realDirtyRect = SkRect::MakeWH(dirtyRect.width() * scale,
283fa807bd31774157959640810e564fbe64338e8e3Nicolas Roard                                          dirtyRect.height() * scale);
284fa807bd31774157959640810e564fbe64338e8e3Nicolas Roard    realDirtyRect.offset(dirtyRect.fLeft * scale, dirtyRect.fTop * scale);
285fa807bd31774157959640810e564fbe64338e8e3Nicolas Roard
286fa807bd31774157959640810e564fbe64338e8e3Nicolas Roard    if (!realTileRect.intersect(realDirtyRect))
287fa807bd31774157959640810e564fbe64338e8e3Nicolas Roard        return false;
288fa807bd31774157959640810e564fbe64338e8e3Nicolas Roard    return true;
289fa807bd31774157959640810e564fbe64338e8e3Nicolas Roard}
290fa807bd31774157959640810e564fbe64338e8e3Nicolas Roard
291594c6b805969c2673c84d1d1d1a3556ce376ac7aChris Craikbool Tile::isTileVisible(const IntRect& viewTileBounds)
292e48d27773894f36d85e5c2e2052ab90d502e1c72Chris Craik{
293e48d27773894f36d85e5c2e2052ab90d502e1c72Chris Craik    return (m_x >= viewTileBounds.x()
294e48d27773894f36d85e5c2e2052ab90d502e1c72Chris Craik            && m_x < viewTileBounds.x() + viewTileBounds.width()
295e48d27773894f36d85e5c2e2052ab90d502e1c72Chris Craik            && m_y >= viewTileBounds.y()
296e48d27773894f36d85e5c2e2052ab90d502e1c72Chris Craik            && m_y < viewTileBounds.y() + viewTileBounds.height());
297e48d27773894f36d85e5c2e2052ab90d502e1c72Chris Craik}
298e48d27773894f36d85e5c2e2052ab90d502e1c72Chris Craik
2993a7a2aa023d51b1806d4063ab0ea5ef7d488556fNicolas Roard// This is called from the texture generation thread
300594c6b805969c2673c84d1d1d1a3556ce376ac7aChris Craikvoid Tile::paintBitmap(TilePainter* painter)
301a5ffb7c279df240a07658953e1bd5df6d0480cb6Nicolas Roard{
302a1e806ed3b2d9e2727d08cc2a3958fce501f6f33Derek Sollenberger    // We acquire the values below atomically. This ensures that we are reading
303a1e806ed3b2d9e2727d08cc2a3958fce501f6f33Derek Sollenberger    // values correctly across cores. Further, once we have these values they
304a1e806ed3b2d9e2727d08cc2a3958fce501f6f33Derek Sollenberger    // can be updated by other threads without consequence.
305a1e806ed3b2d9e2727d08cc2a3958fce501f6f33Derek Sollenberger    m_atomicSync.lock();
306a1e806ed3b2d9e2727d08cc2a3958fce501f6f33Derek Sollenberger    bool dirty = m_dirty;
307594c6b805969c2673c84d1d1d1a3556ce376ac7aChris Craik    TileTexture* texture = m_backTexture;
30862ee9670dd9beeb9a8f21d8737250c081382e2f5Teng-Hui Zhu    SkRegion dirtyArea = m_dirtyArea;
3093a7a2aa023d51b1806d4063ab0ea5ef7d488556fNicolas Roard    float scale = m_scale;
310be61abb47b98988ca94bd839a1e17c3267365dc9Nicolas Roard    const int x = m_x;
311be61abb47b98988ca94bd839a1e17c3267365dc9Nicolas Roard    const int y = m_y;
312cf1ae53e7b2853d1148ecd784379f12dffda9d43Nicolas Roard
3133c131605fca8e29a88fdc4923d86bdc3f40adb2bNicolas Roard    if (!dirty || !texture) {
3143c131605fca8e29a88fdc4923d86bdc3f40adb2bNicolas Roard        m_atomicSync.unlock();
31575394f5ee0aac2337cdff1597b4e686e22c52833Nicolas Roard        return;
3163c131605fca8e29a88fdc4923d86bdc3f40adb2bNicolas Roard    }
317f6a40880028cf495025747229c627f42e25acc66Chris Craik    if (m_state != Unpainted) {
318d487c56b47c747d3e331ee1892e4c0473363afd2Chris Craik        ALOGV("Warning: started painting tile %p, but was at state %d, ft %p bt %p",
319f6a40880028cf495025747229c627f42e25acc66Chris Craik              this, m_state, m_frontTexture, m_backTexture);
320f6a40880028cf495025747229c627f42e25acc66Chris Craik    }
321f6a40880028cf495025747229c627f42e25acc66Chris Craik    m_state = PaintingStarted;
32262ee9670dd9beeb9a8f21d8737250c081382e2f5Teng-Hui Zhu    TextureInfo* textureInfo = texture->getTextureInfo();
3233c131605fca8e29a88fdc4923d86bdc3f40adb2bNicolas Roard    m_atomicSync.unlock();
324a52793c453c1512d0a18d4ae3108a975f998ae45Derek Sollenberger
325a1e806ed3b2d9e2727d08cc2a3958fce501f6f33Derek Sollenberger    // at this point we can safely check the ownership (if the texture got
326594c6b805969c2673c84d1d1d1a3556ce376ac7aChris Craik    // transferred to another Tile under us)
3278ad3ab0e47f0d5039e89c1873c178f538ec1b0dfChris Craik    if (texture->owner() != this) {
32875394f5ee0aac2337cdff1597b4e686e22c52833Nicolas Roard        return;
329a5ffb7c279df240a07658953e1bd5df6d0480cb6Nicolas Roard    }
330a5ffb7c279df240a07658953e1bd5df6d0480cb6Nicolas Roard
331c7e578330aece3c556ef205365c24676687223e2Derek Sollenberger    // swap out the renderer if necessary
332c7e578330aece3c556ef205365c24676687223e2Derek Sollenberger    BaseRenderer::swapRendererIfNeeded(m_renderer);
333232d0b3572d13d9b4fb1211d9d56252a1ede3ed6Derek Sollenberger    // setup the common renderInfo fields;
334232d0b3572d13d9b4fb1211d9d56252a1ede3ed6Derek Sollenberger    TileRenderInfo renderInfo;
335232d0b3572d13d9b4fb1211d9d56252a1ede3ed6Derek Sollenberger    renderInfo.x = x;
336232d0b3572d13d9b4fb1211d9d56252a1ede3ed6Derek Sollenberger    renderInfo.y = y;
337232d0b3572d13d9b4fb1211d9d56252a1ede3ed6Derek Sollenberger    renderInfo.scale = scale;
338232d0b3572d13d9b4fb1211d9d56252a1ede3ed6Derek Sollenberger    renderInfo.tileSize = texture->getSize();
3393c131605fca8e29a88fdc4923d86bdc3f40adb2bNicolas Roard    renderInfo.tilePainter = painter;
3403c131605fca8e29a88fdc4923d86bdc3f40adb2bNicolas Roard    renderInfo.baseTile = this;
341232d0b3572d13d9b4fb1211d9d56252a1ede3ed6Derek Sollenberger    renderInfo.textureInfo = textureInfo;
342232d0b3572d13d9b4fb1211d9d56252a1ede3ed6Derek Sollenberger
343232d0b3572d13d9b4fb1211d9d56252a1ede3ed6Derek Sollenberger    const float tileWidth = renderInfo.tileSize.width();
344232d0b3572d13d9b4fb1211d9d56252a1ede3ed6Derek Sollenberger    const float tileHeight = renderInfo.tileSize.height();
345232d0b3572d13d9b4fb1211d9d56252a1ede3ed6Derek Sollenberger
346e859a34171f2a36877d95197d118d962078f8aa0John Reck    m_renderer->renderTiledContent(renderInfo);
347fca6a67b130c1f97d366460af412ec6e6de14834Derek Sollenberger
34867e4aa15702646d5ff50e9524f4e63eb9ed20122Nicolas Roard    m_atomicSync.lock();
3497c554a61cb935660cdc86905d040c781b490150fTeng-Hui Zhu
3508ad3ab0e47f0d5039e89c1873c178f538ec1b0dfChris Craik    if (texture == m_backTexture) {
3515ba4a087b9212ca9ae083f015637f417199d85ccJohn Reck        // set the fullrepaint flags
35262ee9670dd9beeb9a8f21d8737250c081382e2f5Teng-Hui Zhu        m_fullRepaint = false;
35367e4aa15702646d5ff50e9524f4e63eb9ed20122Nicolas Roard
3545ba4a087b9212ca9ae083f015637f417199d85ccJohn Reck        // The various checks to see if we are still dirty...
35567e4aa15702646d5ff50e9524f4e63eb9ed20122Nicolas Roard
3565ba4a087b9212ca9ae083f015637f417199d85ccJohn Reck        m_dirty = false;
35767e4aa15702646d5ff50e9524f4e63eb9ed20122Nicolas Roard
3585ba4a087b9212ca9ae083f015637f417199d85ccJohn Reck        if (m_scale != scale)
3595ba4a087b9212ca9ae083f015637f417199d85ccJohn Reck            m_dirty = true;
36067e4aa15702646d5ff50e9524f4e63eb9ed20122Nicolas Roard
361e859a34171f2a36877d95197d118d962078f8aa0John Reck        m_dirtyArea.setEmpty();
362c15781f45f0d19a925be7fd73bd10c318562db70Nicolas Roard
363d487c56b47c747d3e331ee1892e4c0473363afd2Chris Craik        ALOGV("painted tile %p (%d, %d), texture %p, dirty=%d", this, x, y, texture, m_dirty);
364e733717c7b60d2ccfee9c47af4659ffb8e70dd73Chris Craik
365f6a40880028cf495025747229c627f42e25acc66Chris Craik        validatePaint();
366f6a40880028cf495025747229c627f42e25acc66Chris Craik    } else {
367d487c56b47c747d3e331ee1892e4c0473363afd2Chris Craik        ALOGV("tile %p no longer owns texture %p, m_state %d. ft %p bt %p",
368d487c56b47c747d3e331ee1892e4c0473363afd2Chris Craik              this, texture, m_state, m_frontTexture, m_backTexture);
3695ba4a087b9212ca9ae083f015637f417199d85ccJohn Reck    }
37067e4aa15702646d5ff50e9524f4e63eb9ed20122Nicolas Roard
37167e4aa15702646d5ff50e9524f4e63eb9ed20122Nicolas Roard    m_atomicSync.unlock();
37267e4aa15702646d5ff50e9524f4e63eb9ed20122Nicolas Roard}
37367e4aa15702646d5ff50e9524f4e63eb9ed20122Nicolas Roard
374594c6b805969c2673c84d1d1d1a3556ce376ac7aChris Craikvoid Tile::discardTextures() {
3758ad3ab0e47f0d5039e89c1873c178f538ec1b0dfChris Craik    android::AutoMutex lock(m_atomicSync);
376d487c56b47c747d3e331ee1892e4c0473363afd2Chris Craik    ALOGV("%p discarding bt %p, ft %p",
377d487c56b47c747d3e331ee1892e4c0473363afd2Chris Craik          this, m_backTexture, m_frontTexture);
3788ad3ab0e47f0d5039e89c1873c178f538ec1b0dfChris Craik    if (m_frontTexture) {
3798ad3ab0e47f0d5039e89c1873c178f538ec1b0dfChris Craik        m_frontTexture->release(this);
3808ad3ab0e47f0d5039e89c1873c178f538ec1b0dfChris Craik        m_frontTexture = 0;
3818ad3ab0e47f0d5039e89c1873c178f538ec1b0dfChris Craik    }
3828ad3ab0e47f0d5039e89c1873c178f538ec1b0dfChris Craik    if (m_backTexture) {
3838ad3ab0e47f0d5039e89c1873c178f538ec1b0dfChris Craik        m_backTexture->release(this);
3848ad3ab0e47f0d5039e89c1873c178f538ec1b0dfChris Craik        m_backTexture = 0;
3858ad3ab0e47f0d5039e89c1873c178f538ec1b0dfChris Craik    }
38662ee9670dd9beeb9a8f21d8737250c081382e2f5Teng-Hui Zhu    m_dirtyArea.setEmpty();
38762ee9670dd9beeb9a8f21d8737250c081382e2f5Teng-Hui Zhu    m_fullRepaint = true;
38862ee9670dd9beeb9a8f21d8737250c081382e2f5Teng-Hui Zhu
3898ad3ab0e47f0d5039e89c1873c178f538ec1b0dfChris Craik    m_dirty = true;
390f6a40880028cf495025747229c627f42e25acc66Chris Craik    m_state = Unpainted;
3918ad3ab0e47f0d5039e89c1873c178f538ec1b0dfChris Craik}
3928ad3ab0e47f0d5039e89c1873c178f538ec1b0dfChris Craik
393594c6b805969c2673c84d1d1d1a3556ce376ac7aChris Craikvoid Tile::discardBackTexture() {
3943a819aac70dd26f675644f6a35b13be5fb3de2f1Chris Craik    android::AutoMutex lock(m_atomicSync);
3953a819aac70dd26f675644f6a35b13be5fb3de2f1Chris Craik    if (m_backTexture) {
3963a819aac70dd26f675644f6a35b13be5fb3de2f1Chris Craik        m_backTexture->release(this);
3973a819aac70dd26f675644f6a35b13be5fb3de2f1Chris Craik        m_backTexture = 0;
3983a819aac70dd26f675644f6a35b13be5fb3de2f1Chris Craik    }
3993ef9d5cc655b8274860b8d15441201d3e621baf5Chris Craik    m_state = Unpainted;
4003ef9d5cc655b8274860b8d15441201d3e621baf5Chris Craik    m_dirty = true;
4013a819aac70dd26f675644f6a35b13be5fb3de2f1Chris Craik}
4023a819aac70dd26f675644f6a35b13be5fb3de2f1Chris Craik
403594c6b805969c2673c84d1d1d1a3556ce376ac7aChris Craikbool Tile::swapTexturesIfNeeded() {
4048ad3ab0e47f0d5039e89c1873c178f538ec1b0dfChris Craik    android::AutoMutex lock(m_atomicSync);
405f6a40880028cf495025747229c627f42e25acc66Chris Craik    if (m_state == ReadyToSwap) {
4068ad3ab0e47f0d5039e89c1873c178f538ec1b0dfChris Craik        // discard old texture and swap the new one in its place
4078ad3ab0e47f0d5039e89c1873c178f538ec1b0dfChris Craik        if (m_frontTexture)
4088ad3ab0e47f0d5039e89c1873c178f538ec1b0dfChris Craik            m_frontTexture->release(this);
4098ad3ab0e47f0d5039e89c1873c178f538ec1b0dfChris Craik
4108ad3ab0e47f0d5039e89c1873c178f538ec1b0dfChris Craik        m_frontTexture = m_backTexture;
4118ad3ab0e47f0d5039e89c1873c178f538ec1b0dfChris Craik        m_backTexture = 0;
412f6a40880028cf495025747229c627f42e25acc66Chris Craik        m_state = UpToDate;
413d487c56b47c747d3e331ee1892e4c0473363afd2Chris Craik        ALOGV("display texture for %p at %d, %d front is now %p, back is %p",
414d487c56b47c747d3e331ee1892e4c0473363afd2Chris Craik              this, m_x, m_y, m_frontTexture, m_backTexture);
415f6a40880028cf495025747229c627f42e25acc66Chris Craik
4168ad3ab0e47f0d5039e89c1873c178f538ec1b0dfChris Craik        return true;
4178ad3ab0e47f0d5039e89c1873c178f538ec1b0dfChris Craik    }
4188ad3ab0e47f0d5039e89c1873c178f538ec1b0dfChris Craik    return false;
4198ad3ab0e47f0d5039e89c1873c178f538ec1b0dfChris Craik}
4208ad3ab0e47f0d5039e89c1873c178f538ec1b0dfChris Craik
421594c6b805969c2673c84d1d1d1a3556ce376ac7aChris Craikvoid Tile::backTextureTransfer() {
422f6a40880028cf495025747229c627f42e25acc66Chris Craik    android::AutoMutex lock(m_atomicSync);
423f6a40880028cf495025747229c627f42e25acc66Chris Craik    if (m_state == PaintingStarted)
424f6a40880028cf495025747229c627f42e25acc66Chris Craik        m_state = TransferredUnvalidated;
425f6a40880028cf495025747229c627f42e25acc66Chris Craik    else if (m_state == ValidatedUntransferred)
426f6a40880028cf495025747229c627f42e25acc66Chris Craik        m_state = ReadyToSwap;
427f6a40880028cf495025747229c627f42e25acc66Chris Craik    else {
428f6a40880028cf495025747229c627f42e25acc66Chris Craik        // shouldn't have transferred a tile in any other state, log
429d487c56b47c747d3e331ee1892e4c0473363afd2Chris Craik        ALOGV("Note: transferred tile %p at %d %d, state wasn't paintingstarted or validated: %d",
430d487c56b47c747d3e331ee1892e4c0473363afd2Chris Craik              this, m_x, m_y, m_state);
431f6a40880028cf495025747229c627f42e25acc66Chris Craik    }
432f6a40880028cf495025747229c627f42e25acc66Chris Craik}
433f6a40880028cf495025747229c627f42e25acc66Chris Craik
434594c6b805969c2673c84d1d1d1a3556ce376ac7aChris Craikvoid Tile::backTextureTransferFail() {
435530c83c6351e05a6939ad0b5bc291da073e77b5bChris Craik    // transfer failed for some reason, mark dirty so it will (repaint and) be
436530c83c6351e05a6939ad0b5bc291da073e77b5bChris Craik    // retransferred.
437530c83c6351e05a6939ad0b5bc291da073e77b5bChris Craik    android::AutoMutex lock(m_atomicSync);
438530c83c6351e05a6939ad0b5bc291da073e77b5bChris Craik    m_state = Unpainted;
4393ef9d5cc655b8274860b8d15441201d3e621baf5Chris Craik    m_dirty = true;
440530c83c6351e05a6939ad0b5bc291da073e77b5bChris Craik    // whether validatePaint is called before or after, it won't do anything
441530c83c6351e05a6939ad0b5bc291da073e77b5bChris Craik}
442530c83c6351e05a6939ad0b5bc291da073e77b5bChris Craik
443e859a34171f2a36877d95197d118d962078f8aa0John Reckvoid Tile::onBlitUpdate()
444e859a34171f2a36877d95197d118d962078f8aa0John Reck{
445e859a34171f2a36877d95197d118d962078f8aa0John Reck    // The front texture was directly updated with a blit, so mark this as clean
446e859a34171f2a36877d95197d118d962078f8aa0John Reck    android::AutoMutex lock(m_atomicSync);
447e859a34171f2a36877d95197d118d962078f8aa0John Reck    m_dirty = false;
448e859a34171f2a36877d95197d118d962078f8aa0John Reck    m_dirtyArea.setEmpty();
449e859a34171f2a36877d95197d118d962078f8aa0John Reck    m_state = Tile::UpToDate;
450e859a34171f2a36877d95197d118d962078f8aa0John Reck}
451e859a34171f2a36877d95197d118d962078f8aa0John Reck
452594c6b805969c2673c84d1d1d1a3556ce376ac7aChris Craikvoid Tile::validatePaint() {
453f6a40880028cf495025747229c627f42e25acc66Chris Craik    // ONLY CALL while m_atomicSync is locked (at the end of paintBitmap())
454f6a40880028cf495025747229c627f42e25acc66Chris Craik
455f6a40880028cf495025747229c627f42e25acc66Chris Craik    if (!m_dirty) {
456f6a40880028cf495025747229c627f42e25acc66Chris Craik        // since after the paint, the tile isn't dirty, 'validate' it - this
457f6a40880028cf495025747229c627f42e25acc66Chris Craik        // may happed before or after the transfer queue operation. Only
458f6a40880028cf495025747229c627f42e25acc66Chris Craik        // when both have happened, mark as 'ReadyToSwap'
459f6a40880028cf495025747229c627f42e25acc66Chris Craik        if (m_state == PaintingStarted)
460f6a40880028cf495025747229c627f42e25acc66Chris Craik            m_state = ValidatedUntransferred;
461309ae897e0ad3493fc6acd97a39c631f90580d57Teng-Hui Zhu        else if (m_state == TransferredUnvalidated) {
4628abedfb0681eb18f62137fffde000a9dbb75c4d2Teng-Hui Zhu            // When the backTexture has been marked pureColor, we will skip the
4638abedfb0681eb18f62137fffde000a9dbb75c4d2Teng-Hui Zhu            // transfer and marked as ReadyToSwap, in this case, we don't want
4648abedfb0681eb18f62137fffde000a9dbb75c4d2Teng-Hui Zhu            // to reset m_dirty bit to true.
465f6a40880028cf495025747229c627f42e25acc66Chris Craik            m_state = ReadyToSwap;
4668abedfb0681eb18f62137fffde000a9dbb75c4d2Teng-Hui Zhu        } else {
467d487c56b47c747d3e331ee1892e4c0473363afd2Chris Craik            ALOGV("Note: validated tile %p at %d %d, state wasn't paintingstarted or transferred %d",
468f6a40880028cf495025747229c627f42e25acc66Chris Craik                  this, m_x, m_y, m_state);
4693ef9d5cc655b8274860b8d15441201d3e621baf5Chris Craik            // failed transferring, in which case mark dirty (since
4703ef9d5cc655b8274860b8d15441201d3e621baf5Chris Craik            // paintBitmap() may have cleared m_dirty)
4713ef9d5cc655b8274860b8d15441201d3e621baf5Chris Craik            m_dirty = true;
472f6a40880028cf495025747229c627f42e25acc66Chris Craik        }
473f6a40880028cf495025747229c627f42e25acc66Chris Craik    } else {
474d487c56b47c747d3e331ee1892e4c0473363afd2Chris Craik        ALOGV("Note: paint was unsuccessful.");
475f6a40880028cf495025747229c627f42e25acc66Chris Craik        m_state = Unpainted;
476f6a40880028cf495025747229c627f42e25acc66Chris Craik    }
477f6a40880028cf495025747229c627f42e25acc66Chris Craik
478f6a40880028cf495025747229c627f42e25acc66Chris Craik}
479f6a40880028cf495025747229c627f42e25acc66Chris Craik
480a5ffb7c279df240a07658953e1bd5df6d0480cb6Nicolas Roard} // namespace WebCore
481a5ffb7c279df240a07658953e1bd5df6d0480cb6Nicolas Roard
482a5ffb7c279df240a07658953e1bd5df6d0480cb6Nicolas Roard#endif // USE(ACCELERATED_COMPOSITING)
483