Tile.cpp revision f8f42bbda64a56cfd5ab48a274020d4efc9a5594
1a5ffb7c279df240a07658953e1bd5df6d0480cb6Nicolas Roard/*
2a5ffb7c279df240a07658953e1bd5df6d0480cb6Nicolas Roard * Copyright 2010, The Android Open Source Project
3a5ffb7c279df240a07658953e1bd5df6d0480cb6Nicolas Roard *
4a5ffb7c279df240a07658953e1bd5df6d0480cb6Nicolas Roard * Redistribution and use in source and binary forms, with or without
5a5ffb7c279df240a07658953e1bd5df6d0480cb6Nicolas Roard * modification, are permitted provided that the following conditions
6a5ffb7c279df240a07658953e1bd5df6d0480cb6Nicolas Roard * are met:
7a5ffb7c279df240a07658953e1bd5df6d0480cb6Nicolas Roard *  * Redistributions of source code must retain the above copyright
8a5ffb7c279df240a07658953e1bd5df6d0480cb6Nicolas Roard *    notice, this list of conditions and the following disclaimer.
9a5ffb7c279df240a07658953e1bd5df6d0480cb6Nicolas Roard *  * Redistributions in binary form must reproduce the above copyright
10a5ffb7c279df240a07658953e1bd5df6d0480cb6Nicolas Roard *    notice, this list of conditions and the following disclaimer in the
11a5ffb7c279df240a07658953e1bd5df6d0480cb6Nicolas Roard *    documentation and/or other materials provided with the distribution.
12a5ffb7c279df240a07658953e1bd5df6d0480cb6Nicolas Roard *
13a5ffb7c279df240a07658953e1bd5df6d0480cb6Nicolas Roard * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY
14a5ffb7c279df240a07658953e1bd5df6d0480cb6Nicolas Roard * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
15a5ffb7c279df240a07658953e1bd5df6d0480cb6Nicolas Roard * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16a5ffb7c279df240a07658953e1bd5df6d0480cb6Nicolas Roard * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR
17a5ffb7c279df240a07658953e1bd5df6d0480cb6Nicolas Roard * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
18a5ffb7c279df240a07658953e1bd5df6d0480cb6Nicolas Roard * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
19a5ffb7c279df240a07658953e1bd5df6d0480cb6Nicolas Roard * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
20a5ffb7c279df240a07658953e1bd5df6d0480cb6Nicolas Roard * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
21a5ffb7c279df240a07658953e1bd5df6d0480cb6Nicolas Roard * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22a5ffb7c279df240a07658953e1bd5df6d0480cb6Nicolas Roard * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
23a5ffb7c279df240a07658953e1bd5df6d0480cb6Nicolas Roard * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
24a5ffb7c279df240a07658953e1bd5df6d0480cb6Nicolas Roard */
25a5ffb7c279df240a07658953e1bd5df6d0480cb6Nicolas Roard
26a5ffb7c279df240a07658953e1bd5df6d0480cb6Nicolas Roard#include "config.h"
27a5ffb7c279df240a07658953e1bd5df6d0480cb6Nicolas Roard#include "BaseTile.h"
28a5ffb7c279df240a07658953e1bd5df6d0480cb6Nicolas Roard
29a5ffb7c279df240a07658953e1bd5df6d0480cb6Nicolas Roard#if USE(ACCELERATED_COMPOSITING)
30a5ffb7c279df240a07658953e1bd5df6d0480cb6Nicolas Roard
31a5ffb7c279df240a07658953e1bd5df6d0480cb6Nicolas Roard#include "GLUtils.h"
32f85cf343a02e85633e6b68c7f5db3c033b780607Teng-Hui Zhu#include "RasterRenderer.h"
33fca6a67b130c1f97d366460af412ec6e6de14834Derek Sollenberger#include "TextureInfo.h"
34a5ffb7c279df240a07658953e1bd5df6d0480cb6Nicolas Roard#include "TilesManager.h"
35a5ffb7c279df240a07658953e1bd5df6d0480cb6Nicolas Roard
363a7a2aa023d51b1806d4063ab0ea5ef7d488556fNicolas Roard#include <cutils/atomic.h>
37a5ffb7c279df240a07658953e1bd5df6d0480cb6Nicolas Roard
38a5ffb7c279df240a07658953e1bd5df6d0480cb6Nicolas Roard#include <cutils/log.h>
39a5ffb7c279df240a07658953e1bd5df6d0480cb6Nicolas Roard#include <wtf/CurrentTime.h>
40fca6a67b130c1f97d366460af412ec6e6de14834Derek Sollenberger#include <wtf/text/CString.h>
41a5ffb7c279df240a07658953e1bd5df6d0480cb6Nicolas Roard
42e733717c7b60d2ccfee9c47af4659ffb8e70dd73Chris Craik#undef XLOGC
43e733717c7b60d2ccfee9c47af4659ffb8e70dd73Chris Craik#define XLOGC(...) android_printLog(ANDROID_LOG_DEBUG, "BaseTile", __VA_ARGS__)
44e733717c7b60d2ccfee9c47af4659ffb8e70dd73Chris Craik
45e733717c7b60d2ccfee9c47af4659ffb8e70dd73Chris Craik#ifdef DEBUG
46e733717c7b60d2ccfee9c47af4659ffb8e70dd73Chris Craik
47a5ffb7c279df240a07658953e1bd5df6d0480cb6Nicolas Roard#undef XLOG
48a5ffb7c279df240a07658953e1bd5df6d0480cb6Nicolas Roard#define XLOG(...) android_printLog(ANDROID_LOG_DEBUG, "BaseTile", __VA_ARGS__)
49a5ffb7c279df240a07658953e1bd5df6d0480cb6Nicolas Roard
50a5ffb7c279df240a07658953e1bd5df6d0480cb6Nicolas Roard#else
51a5ffb7c279df240a07658953e1bd5df6d0480cb6Nicolas Roard
52a5ffb7c279df240a07658953e1bd5df6d0480cb6Nicolas Roard#undef XLOG
53a5ffb7c279df240a07658953e1bd5df6d0480cb6Nicolas Roard#define XLOG(...)
54a5ffb7c279df240a07658953e1bd5df6d0480cb6Nicolas Roard
55a5ffb7c279df240a07658953e1bd5df6d0480cb6Nicolas Roard#endif // DEBUG
56a5ffb7c279df240a07658953e1bd5df6d0480cb6Nicolas Roard
57c048426c23be795d3bf870e47429167b4157a2d6Nicolas Roard// If the dirty portion of a tile exceeds this ratio, fully repaint.
58c048426c23be795d3bf870e47429167b4157a2d6Nicolas Roard// Lower values give fewer partial repaints, thus fewer front-to-back
59c048426c23be795d3bf870e47429167b4157a2d6Nicolas Roard// texture copies (cost will vary by device). It's a tradeoff between
60c048426c23be795d3bf870e47429167b4157a2d6Nicolas Roard// the rasterization cost and the FBO texture recopy cost when using
61c048426c23be795d3bf870e47429167b4157a2d6Nicolas Roard// GPU for the transfer queue.
62c048426c23be795d3bf870e47429167b4157a2d6Nicolas Roard#define MAX_INVAL_AREA 0.6
63c048426c23be795d3bf870e47429167b4157a2d6Nicolas Roard
64a5ffb7c279df240a07658953e1bd5df6d0480cb6Nicolas Roardnamespace WebCore {
65a5ffb7c279df240a07658953e1bd5df6d0480cb6Nicolas Roard
663c131605fca8e29a88fdc4923d86bdc3f40adb2bNicolas RoardBaseTile::BaseTile(bool isLayerTile)
6772a76070d36a51926c224d230f1503c46f30da60Chris Craik    : m_glWebViewState(0)
683c131605fca8e29a88fdc4923d86bdc3f40adb2bNicolas Roard    , m_painter(0)
69ffc715a2e6382fe9e331557c35fafc426507b8f5Derek Sollenberger    , m_x(-1)
70ffc715a2e6382fe9e331557c35fafc426507b8f5Derek Sollenberger    , m_y(-1)
713c131605fca8e29a88fdc4923d86bdc3f40adb2bNicolas Roard    , m_page(0)
728ad3ab0e47f0d5039e89c1873c178f538ec1b0dfChris Craik    , m_frontTexture(0)
738ad3ab0e47f0d5039e89c1873c178f538ec1b0dfChris Craik    , m_backTexture(0)
74a5ffb7c279df240a07658953e1bd5df6d0480cb6Nicolas Roard    , m_scale(1)
75a1e806ed3b2d9e2727d08cc2a3958fce501f6f33Derek Sollenberger    , m_dirty(true)
76417789b7c56928a5fcb610583346d07ffa380900John Reck    , m_repaintPending(false)
77a1e806ed3b2d9e2727d08cc2a3958fce501f6f33Derek Sollenberger    , m_lastDirtyPicture(0)
7862ee9670dd9beeb9a8f21d8737250c081382e2f5Teng-Hui Zhu    , m_fullRepaint(true)
79fa807bd31774157959640810e564fbe64338e8e3Nicolas Roard    , m_isTexturePainted(false)
803c131605fca8e29a88fdc4923d86bdc3f40adb2bNicolas Roard    , m_isLayerTile(isLayerTile)
818ad3ab0e47f0d5039e89c1873c178f538ec1b0dfChris Craik    , m_drawCount(0)
82f6a40880028cf495025747229c627f42e25acc66Chris Craik    , m_state(Unpainted)
83a5ffb7c279df240a07658953e1bd5df6d0480cb6Nicolas Roard{
84a5ffb7c279df240a07658953e1bd5df6d0480cb6Nicolas Roard#ifdef DEBUG_COUNT
85da44133fe92ec11fa6b904c498e7e5cd23a43cbfNicolas Roard    ClassTracker::instance()->increment("BaseTile");
86a5ffb7c279df240a07658953e1bd5df6d0480cb6Nicolas Roard#endif
87c7e578330aece3c556ef205365c24676687223e2Derek Sollenberger    m_renderer = BaseRenderer::createRenderer();
88a5ffb7c279df240a07658953e1bd5df6d0480cb6Nicolas Roard}
89a5ffb7c279df240a07658953e1bd5df6d0480cb6Nicolas Roard
90a5ffb7c279df240a07658953e1bd5df6d0480cb6Nicolas RoardBaseTile::~BaseTile()
91a5ffb7c279df240a07658953e1bd5df6d0480cb6Nicolas Roard{
928ad3ab0e47f0d5039e89c1873c178f538ec1b0dfChris Craik    if (m_backTexture)
938ad3ab0e47f0d5039e89c1873c178f538ec1b0dfChris Craik        m_backTexture->release(this);
948ad3ab0e47f0d5039e89c1873c178f538ec1b0dfChris Craik    if (m_frontTexture)
958ad3ab0e47f0d5039e89c1873c178f538ec1b0dfChris Craik        m_frontTexture->release(this);
9690455eb70cca2df540942299b35bb3bd8261cb0bDerek Sollenberger
978dfdf8aa25b250ed3b8c0a443cf1cbaf9bd12c5bDerek Sollenberger    delete m_renderer;
988dfdf8aa25b250ed3b8c0a443cf1cbaf9bd12c5bDerek Sollenberger
99a5ffb7c279df240a07658953e1bd5df6d0480cb6Nicolas Roard#ifdef DEBUG_COUNT
100da44133fe92ec11fa6b904c498e7e5cd23a43cbfNicolas Roard    ClassTracker::instance()->decrement("BaseTile");
101a5ffb7c279df240a07658953e1bd5df6d0480cb6Nicolas Roard#endif
102a5ffb7c279df240a07658953e1bd5df6d0480cb6Nicolas Roard}
103a5ffb7c279df240a07658953e1bd5df6d0480cb6Nicolas Roard
1043a7a2aa023d51b1806d4063ab0ea5ef7d488556fNicolas Roard// All the following functions must be called from the main GL thread.
1053a7a2aa023d51b1806d4063ab0ea5ef7d488556fNicolas Roard
1063c131605fca8e29a88fdc4923d86bdc3f40adb2bNicolas Roardvoid BaseTile::setContents(TilePainter* painter, int x, int y, float scale)
107ffc715a2e6382fe9e331557c35fafc426507b8f5Derek Sollenberger{
108d8be9016b7fda67a91b4ee17b3b2e7ba692ee553Chris Craik    // TODO: investigate whether below check/discard is necessary
109d8be9016b7fda67a91b4ee17b3b2e7ba692ee553Chris Craik    if (!painter
1103c131605fca8e29a88fdc4923d86bdc3f40adb2bNicolas Roard        || (m_x != x)
1113c131605fca8e29a88fdc4923d86bdc3f40adb2bNicolas Roard        || (m_y != y)
112f6a40880028cf495025747229c627f42e25acc66Chris Craik        || (m_scale != scale)) {
113f6a40880028cf495025747229c627f42e25acc66Chris Craik        // neither texture is relevant
114f6a40880028cf495025747229c627f42e25acc66Chris Craik        discardTextures();
115f6a40880028cf495025747229c627f42e25acc66Chris Craik    }
1163c131605fca8e29a88fdc4923d86bdc3f40adb2bNicolas Roard
117f6a40880028cf495025747229c627f42e25acc66Chris Craik    android::AutoMutex lock(m_atomicSync);
1183c131605fca8e29a88fdc4923d86bdc3f40adb2bNicolas Roard    m_painter = painter;
119ffc715a2e6382fe9e331557c35fafc426507b8f5Derek Sollenberger    m_x = x;
120ffc715a2e6382fe9e331557c35fafc426507b8f5Derek Sollenberger    m_y = y;
1213c131605fca8e29a88fdc4923d86bdc3f40adb2bNicolas Roard    m_scale = scale;
1228ad3ab0e47f0d5039e89c1873c178f538ec1b0dfChris Craik    m_drawCount = TilesManager::instance()->getDrawGLCount();
123ffc715a2e6382fe9e331557c35fafc426507b8f5Derek Sollenberger}
124ffc715a2e6382fe9e331557c35fafc426507b8f5Derek Sollenberger
125a5ffb7c279df240a07658953e1bd5df6d0480cb6Nicolas Roardvoid BaseTile::reserveTexture()
126a5ffb7c279df240a07658953e1bd5df6d0480cb6Nicolas Roard{
127ec182c75fb35d955a9115fbaf516f648a48ed0e1Derek Sollenberger    BaseTileTexture* texture = TilesManager::instance()->getAvailableTexture(this);
128a1e806ed3b2d9e2727d08cc2a3958fce501f6f33Derek Sollenberger
129a1e806ed3b2d9e2727d08cc2a3958fce501f6f33Derek Sollenberger    android::AutoMutex lock(m_atomicSync);
1308ad3ab0e47f0d5039e89c1873c178f538ec1b0dfChris Craik    if (texture && m_backTexture != texture) {
131959c08a729d39539327aeb634dbce69524e7b678Chris Craik        XLOG("tile %p reserving texture %p, back was %p (front %p)",
132959c08a729d39539327aeb634dbce69524e7b678Chris Craik             this, texture, m_backTexture, m_frontTexture);
133f6a40880028cf495025747229c627f42e25acc66Chris Craik        m_state = Unpainted;
1348ad3ab0e47f0d5039e89c1873c178f538ec1b0dfChris Craik        m_backTexture = texture;
135a1e806ed3b2d9e2727d08cc2a3958fce501f6f33Derek Sollenberger    }
1366aa089bded6a1abbf8d61264588e1e3a32be31b3Chris Craik
137f6a40880028cf495025747229c627f42e25acc66Chris Craik    if (m_state == UpToDate) {
138f6a40880028cf495025747229c627f42e25acc66Chris Craik        XLOG("moving tile %p to unpainted, since it reserved while up to date", this);
1396aa089bded6a1abbf8d61264588e1e3a32be31b3Chris Craik        m_dirty = true;
140f6a40880028cf495025747229c627f42e25acc66Chris Craik        m_state = Unpainted;
141f6a40880028cf495025747229c627f42e25acc66Chris Craik    }
142a5ffb7c279df240a07658953e1bd5df6d0480cb6Nicolas Roard}
143a5ffb7c279df240a07658953e1bd5df6d0480cb6Nicolas Roard
144ec182c75fb35d955a9115fbaf516f648a48ed0e1Derek Sollenbergerbool BaseTile::removeTexture(BaseTileTexture* texture)
145a5ffb7c279df240a07658953e1bd5df6d0480cb6Nicolas Roard{
146959c08a729d39539327aeb634dbce69524e7b678Chris Craik    XLOG("%p removeTexture %p, back %p front %p... page %p",
147959c08a729d39539327aeb634dbce69524e7b678Chris Craik         this, texture, m_backTexture, m_frontTexture, m_page);
1483a7a2aa023d51b1806d4063ab0ea5ef7d488556fNicolas Roard    // We update atomically, so paintBitmap() can see the correct value
149a1e806ed3b2d9e2727d08cc2a3958fce501f6f33Derek Sollenberger    android::AutoMutex lock(m_atomicSync);
150f6a40880028cf495025747229c627f42e25acc66Chris Craik    if (m_frontTexture == texture) {
151f6a40880028cf495025747229c627f42e25acc66Chris Craik        if (m_state == UpToDate) {
152f6a40880028cf495025747229c627f42e25acc66Chris Craik            XLOG("front texture removed, state was UpToDate, now becoming unpainted, bt is %p", m_backTexture);
153f6a40880028cf495025747229c627f42e25acc66Chris Craik            m_state = Unpainted;
154f6a40880028cf495025747229c627f42e25acc66Chris Craik        }
155f6a40880028cf495025747229c627f42e25acc66Chris Craik
1568ad3ab0e47f0d5039e89c1873c178f538ec1b0dfChris Craik        m_frontTexture = 0;
157f6a40880028cf495025747229c627f42e25acc66Chris Craik    }
158f6a40880028cf495025747229c627f42e25acc66Chris Craik    if (m_backTexture == texture) {
159f6a40880028cf495025747229c627f42e25acc66Chris Craik        m_state = Unpainted;
1608ad3ab0e47f0d5039e89c1873c178f538ec1b0dfChris Craik        m_backTexture = 0;
161f6a40880028cf495025747229c627f42e25acc66Chris Craik    }
1626aa089bded6a1abbf8d61264588e1e3a32be31b3Chris Craik
1636aa089bded6a1abbf8d61264588e1e3a32be31b3Chris Craik    // mark dirty regardless of which texture was taken - the back texture may
1646aa089bded6a1abbf8d61264588e1e3a32be31b3Chris Craik    // have been ready to swap
1656aa089bded6a1abbf8d61264588e1e3a32be31b3Chris Craik    m_dirty = true;
1666aa089bded6a1abbf8d61264588e1e3a32be31b3Chris Craik
16781ec1fafcb2c1bc433ec34b6ae4ea78d1ea7d3a8Nicolas Roard    return true;
1683a7a2aa023d51b1806d4063ab0ea5ef7d488556fNicolas Roard}
1693a7a2aa023d51b1806d4063ab0ea5ef7d488556fNicolas Roard
17067e4aa15702646d5ff50e9524f4e63eb9ed20122Nicolas Roardvoid BaseTile::markAsDirty(int unsigned pictureCount,
17167e4aa15702646d5ff50e9524f4e63eb9ed20122Nicolas Roard                           const SkRegion& dirtyArea)
172a1e806ed3b2d9e2727d08cc2a3958fce501f6f33Derek Sollenberger{
173fa807bd31774157959640810e564fbe64338e8e3Nicolas Roard    if (dirtyArea.isEmpty())
174fa807bd31774157959640810e564fbe64338e8e3Nicolas Roard        return;
175a1e806ed3b2d9e2727d08cc2a3958fce501f6f33Derek Sollenberger    android::AutoMutex lock(m_atomicSync);
176a1e806ed3b2d9e2727d08cc2a3958fce501f6f33Derek Sollenberger    m_lastDirtyPicture = pictureCount;
17762ee9670dd9beeb9a8f21d8737250c081382e2f5Teng-Hui Zhu    m_dirtyArea.op(dirtyArea, SkRegion::kUnion_Op);
17861a908361c8a96eeb70afdb5430e89845edb2bddNicolas Roard
17961a908361c8a96eeb70afdb5430e89845edb2bddNicolas Roard    // Check if we actually intersect with the area
18061a908361c8a96eeb70afdb5430e89845edb2bddNicolas Roard    bool intersect = false;
18161a908361c8a96eeb70afdb5430e89845edb2bddNicolas Roard    SkRegion::Iterator cliperator(dirtyArea);
18261a908361c8a96eeb70afdb5430e89845edb2bddNicolas Roard    int tileWidth = TilesManager::instance()->tileWidth();
18361a908361c8a96eeb70afdb5430e89845edb2bddNicolas Roard    int tileHeight = TilesManager::instance()->tileHeight();
18461a908361c8a96eeb70afdb5430e89845edb2bddNicolas Roard    if (m_isLayerTile) {
18561a908361c8a96eeb70afdb5430e89845edb2bddNicolas Roard        tileWidth = TilesManager::instance()->layerTileWidth();
18661a908361c8a96eeb70afdb5430e89845edb2bddNicolas Roard        tileHeight = TilesManager::instance()->layerTileHeight();
18761a908361c8a96eeb70afdb5430e89845edb2bddNicolas Roard    }
18861a908361c8a96eeb70afdb5430e89845edb2bddNicolas Roard    SkRect realTileRect;
18961a908361c8a96eeb70afdb5430e89845edb2bddNicolas Roard    SkRect dirtyRect;
19061a908361c8a96eeb70afdb5430e89845edb2bddNicolas Roard    while (!cliperator.done()) {
19161a908361c8a96eeb70afdb5430e89845edb2bddNicolas Roard        dirtyRect.set(cliperator.rect());
19261a908361c8a96eeb70afdb5430e89845edb2bddNicolas Roard        if (intersectWithRect(m_x, m_y, tileWidth, tileHeight,
19361a908361c8a96eeb70afdb5430e89845edb2bddNicolas Roard                              m_scale, dirtyRect, realTileRect)) {
19461a908361c8a96eeb70afdb5430e89845edb2bddNicolas Roard            intersect = true;
19561a908361c8a96eeb70afdb5430e89845edb2bddNicolas Roard            break;
19661a908361c8a96eeb70afdb5430e89845edb2bddNicolas Roard        }
19761a908361c8a96eeb70afdb5430e89845edb2bddNicolas Roard        cliperator.next();
19861a908361c8a96eeb70afdb5430e89845edb2bddNicolas Roard    }
19908c253c5d2dad921120c3e1ab7bc6781064ca31bNicolas Roard
20061a908361c8a96eeb70afdb5430e89845edb2bddNicolas Roard    if (!intersect)
20161a908361c8a96eeb70afdb5430e89845edb2bddNicolas Roard        return;
20261a908361c8a96eeb70afdb5430e89845edb2bddNicolas Roard
20367e4aa15702646d5ff50e9524f4e63eb9ed20122Nicolas Roard    m_dirty = true;
204f6a40880028cf495025747229c627f42e25acc66Chris Craik    if (m_state == UpToDate) {
205f6a40880028cf495025747229c627f42e25acc66Chris Craik        // We only mark a tile as unpainted in 'markAsDirty' if its status is
206f6a40880028cf495025747229c627f42e25acc66Chris Craik        // UpToDate: marking dirty means we need to repaint, but don't stop the
207f6a40880028cf495025747229c627f42e25acc66Chris Craik        // current paint
208f6a40880028cf495025747229c627f42e25acc66Chris Craik        m_state = Unpainted;
209f6a40880028cf495025747229c627f42e25acc66Chris Craik    } else if (m_state != Unpainted) {
210f6a40880028cf495025747229c627f42e25acc66Chris Craik        // TODO: fix it so that they can paint while deferring the markAsDirty
211f6a40880028cf495025747229c627f42e25acc66Chris Craik        // call (or block updates)
212f6a40880028cf495025747229c627f42e25acc66Chris Craik        XLOG("Warning: tried to mark tile %p at %d, %d islayertile %d as dirty, state %d, page %p",
213f6a40880028cf495025747229c627f42e25acc66Chris Craik              this, m_x, m_y, isLayerTile(), m_state, m_page);
214458b4b11924c3bcc70dcdd3d69f64a855870e72dChris Craik
215458b4b11924c3bcc70dcdd3d69f64a855870e72dChris Craik        // prefetch tiles can be marked dirty while in the process of painting,
216458b4b11924c3bcc70dcdd3d69f64a855870e72dChris Craik        // due to not using an update lock. force them to fail validate step.
217458b4b11924c3bcc70dcdd3d69f64a855870e72dChris Craik        m_state = Unpainted;
218f6a40880028cf495025747229c627f42e25acc66Chris Craik    }
219a1e806ed3b2d9e2727d08cc2a3958fce501f6f33Derek Sollenberger}
220a1e806ed3b2d9e2727d08cc2a3958fce501f6f33Derek Sollenberger
221a1e806ed3b2d9e2727d08cc2a3958fce501f6f33Derek Sollenbergerbool BaseTile::isDirty()
222a1e806ed3b2d9e2727d08cc2a3958fce501f6f33Derek Sollenberger{
223a1e806ed3b2d9e2727d08cc2a3958fce501f6f33Derek Sollenberger    android::AutoMutex lock(m_atomicSync);
224a1e806ed3b2d9e2727d08cc2a3958fce501f6f33Derek Sollenberger    return m_dirty;
225a5ffb7c279df240a07658953e1bd5df6d0480cb6Nicolas Roard}
226a5ffb7c279df240a07658953e1bd5df6d0480cb6Nicolas Roard
227417789b7c56928a5fcb610583346d07ffa380900John Reckbool BaseTile::isRepaintPending()
228417789b7c56928a5fcb610583346d07ffa380900John Reck{
229417789b7c56928a5fcb610583346d07ffa380900John Reck    android::AutoMutex lock(m_atomicSync);
230417789b7c56928a5fcb610583346d07ffa380900John Reck    return m_repaintPending;
231417789b7c56928a5fcb610583346d07ffa380900John Reck}
232417789b7c56928a5fcb610583346d07ffa380900John Reck
233417789b7c56928a5fcb610583346d07ffa380900John Reckvoid BaseTile::setRepaintPending(bool pending)
234417789b7c56928a5fcb610583346d07ffa380900John Reck{
235417789b7c56928a5fcb610583346d07ffa380900John Reck    android::AutoMutex lock(m_atomicSync);
236417789b7c56928a5fcb610583346d07ffa380900John Reck    m_repaintPending = pending;
237417789b7c56928a5fcb610583346d07ffa380900John Reck}
238417789b7c56928a5fcb610583346d07ffa380900John Reck
239e6a08abad427194f5eb95ba75b77211fa8498997Chris Craikvoid BaseTile::drawGL(float opacity, const SkRect& rect, float scale,
240e6a08abad427194f5eb95ba75b77211fa8498997Chris Craik                      const TransformationMatrix* transform)
241a5ffb7c279df240a07658953e1bd5df6d0480cb6Nicolas Roard{
2421deed5ff76dad5d0783c0e07639338f1d6b08a67Nicolas Roard    if (m_x < 0 || m_y < 0 || m_scale != scale)
24367e4aa15702646d5ff50e9524f4e63eb9ed20122Nicolas Roard        return;
24467e4aa15702646d5ff50e9524f4e63eb9ed20122Nicolas Roard
2458ad3ab0e47f0d5039e89c1873c178f538ec1b0dfChris Craik    // No need to mutex protect reads of m_backTexture as it is only written to by
246a1e806ed3b2d9e2727d08cc2a3958fce501f6f33Derek Sollenberger    // the consumer thread.
2478ad3ab0e47f0d5039e89c1873c178f538ec1b0dfChris Craik    if (!m_frontTexture)
248a5ffb7c279df240a07658953e1bd5df6d0480cb6Nicolas Roard        return;
249a5ffb7c279df240a07658953e1bd5df6d0480cb6Nicolas Roard
250c9ab9bf00ba3ce8289f917675f81b40e4438a864Teng-Hui Zhu    // Early return if set to un-usable in purpose!
2510bdd7f2d73cad03535071e5de0ba3d2f5feb1b00Teng-Hui Zhu    m_atomicSync.lock();
252fa807bd31774157959640810e564fbe64338e8e3Nicolas Roard    bool isTexturePainted = m_isTexturePainted;
2530bdd7f2d73cad03535071e5de0ba3d2f5feb1b00Teng-Hui Zhu    m_atomicSync.unlock();
2548ad3ab0e47f0d5039e89c1873c178f538ec1b0dfChris Craik
2558ad3ab0e47f0d5039e89c1873c178f538ec1b0dfChris Craik    if (!isTexturePainted)
256c9ab9bf00ba3ce8289f917675f81b40e4438a864Teng-Hui Zhu        return;
257c9ab9bf00ba3ce8289f917675f81b40e4438a864Teng-Hui Zhu
258f8f42bbda64a56cfd5ab48a274020d4efc9a5594Chris Craik    m_frontTexture->drawGL(isLayerTile(), rect, opacity, transform);
259a5ffb7c279df240a07658953e1bd5df6d0480cb6Nicolas Roard}
260a5ffb7c279df240a07658953e1bd5df6d0480cb6Nicolas Roard
261a1e806ed3b2d9e2727d08cc2a3958fce501f6f33Derek Sollenbergerbool BaseTile::isTileReady()
262a5ffb7c279df240a07658953e1bd5df6d0480cb6Nicolas Roard{
2638ad3ab0e47f0d5039e89c1873c178f538ec1b0dfChris Craik    // Return true if the tile's most recently drawn texture is up to date
2648ad3ab0e47f0d5039e89c1873c178f538ec1b0dfChris Craik    android::AutoMutex lock(m_atomicSync);
265f6a40880028cf495025747229c627f42e25acc66Chris Craik    BaseTileTexture * texture = (m_state == ReadyToSwap) ? m_backTexture : m_frontTexture;
2668ad3ab0e47f0d5039e89c1873c178f538ec1b0dfChris Craik
2678ad3ab0e47f0d5039e89c1873c178f538ec1b0dfChris Craik    if (!texture)
268a5ffb7c279df240a07658953e1bd5df6d0480cb6Nicolas Roard        return false;
2698ad3ab0e47f0d5039e89c1873c178f538ec1b0dfChris Craik
2708ad3ab0e47f0d5039e89c1873c178f538ec1b0dfChris Craik    if (texture->owner() != this)
271a5ffb7c279df240a07658953e1bd5df6d0480cb6Nicolas Roard        return false;
272a1e806ed3b2d9e2727d08cc2a3958fce501f6f33Derek Sollenberger
27367e4aa15702646d5ff50e9524f4e63eb9ed20122Nicolas Roard    if (m_dirty)
27467e4aa15702646d5ff50e9524f4e63eb9ed20122Nicolas Roard        return false;
27567e4aa15702646d5ff50e9524f4e63eb9ed20122Nicolas Roard
276f6a40880028cf495025747229c627f42e25acc66Chris Craik    if (m_state != ReadyToSwap && m_state != UpToDate)
277f6a40880028cf495025747229c627f42e25acc66Chris Craik        return false;
278f6a40880028cf495025747229c627f42e25acc66Chris Craik
279f8f42bbda64a56cfd5ab48a274020d4efc9a5594Chris Craik    return true;
280a5ffb7c279df240a07658953e1bd5df6d0480cb6Nicolas Roard}
281a5ffb7c279df240a07658953e1bd5df6d0480cb6Nicolas Roard
282fa807bd31774157959640810e564fbe64338e8e3Nicolas Roardbool BaseTile::intersectWithRect(int x, int y, int tileWidth, int tileHeight,
283fa807bd31774157959640810e564fbe64338e8e3Nicolas Roard                                 float scale, const SkRect& dirtyRect,
284fa807bd31774157959640810e564fbe64338e8e3Nicolas Roard                                 SkRect& realTileRect)
285fa807bd31774157959640810e564fbe64338e8e3Nicolas Roard{
286fa807bd31774157959640810e564fbe64338e8e3Nicolas Roard    // compute the rect to corresponds to pixels
287fa807bd31774157959640810e564fbe64338e8e3Nicolas Roard    realTileRect.fLeft = x * tileWidth;
288fa807bd31774157959640810e564fbe64338e8e3Nicolas Roard    realTileRect.fTop = y * tileHeight;
289fa807bd31774157959640810e564fbe64338e8e3Nicolas Roard    realTileRect.fRight = realTileRect.fLeft + tileWidth;
290fa807bd31774157959640810e564fbe64338e8e3Nicolas Roard    realTileRect.fBottom = realTileRect.fTop + tileHeight;
291fa807bd31774157959640810e564fbe64338e8e3Nicolas Roard
292fa807bd31774157959640810e564fbe64338e8e3Nicolas Roard    // scale the dirtyRect for intersect computation.
293fa807bd31774157959640810e564fbe64338e8e3Nicolas Roard    SkRect realDirtyRect = SkRect::MakeWH(dirtyRect.width() * scale,
294fa807bd31774157959640810e564fbe64338e8e3Nicolas Roard                                          dirtyRect.height() * scale);
295fa807bd31774157959640810e564fbe64338e8e3Nicolas Roard    realDirtyRect.offset(dirtyRect.fLeft * scale, dirtyRect.fTop * scale);
296fa807bd31774157959640810e564fbe64338e8e3Nicolas Roard
297fa807bd31774157959640810e564fbe64338e8e3Nicolas Roard    if (!realTileRect.intersect(realDirtyRect))
298fa807bd31774157959640810e564fbe64338e8e3Nicolas Roard        return false;
299fa807bd31774157959640810e564fbe64338e8e3Nicolas Roard    return true;
300fa807bd31774157959640810e564fbe64338e8e3Nicolas Roard}
301fa807bd31774157959640810e564fbe64338e8e3Nicolas Roard
302e48d27773894f36d85e5c2e2052ab90d502e1c72Chris Craikbool BaseTile::isTileVisible(const IntRect& viewTileBounds)
303e48d27773894f36d85e5c2e2052ab90d502e1c72Chris Craik{
304e48d27773894f36d85e5c2e2052ab90d502e1c72Chris Craik    return (m_x >= viewTileBounds.x()
305e48d27773894f36d85e5c2e2052ab90d502e1c72Chris Craik            && m_x < viewTileBounds.x() + viewTileBounds.width()
306e48d27773894f36d85e5c2e2052ab90d502e1c72Chris Craik            && m_y >= viewTileBounds.y()
307e48d27773894f36d85e5c2e2052ab90d502e1c72Chris Craik            && m_y < viewTileBounds.y() + viewTileBounds.height());
308e48d27773894f36d85e5c2e2052ab90d502e1c72Chris Craik}
309e48d27773894f36d85e5c2e2052ab90d502e1c72Chris Craik
3103a7a2aa023d51b1806d4063ab0ea5ef7d488556fNicolas Roard// This is called from the texture generation thread
31175394f5ee0aac2337cdff1597b4e686e22c52833Nicolas Roardvoid BaseTile::paintBitmap()
312a5ffb7c279df240a07658953e1bd5df6d0480cb6Nicolas Roard{
313a1e806ed3b2d9e2727d08cc2a3958fce501f6f33Derek Sollenberger    // We acquire the values below atomically. This ensures that we are reading
314a1e806ed3b2d9e2727d08cc2a3958fce501f6f33Derek Sollenberger    // values correctly across cores. Further, once we have these values they
315a1e806ed3b2d9e2727d08cc2a3958fce501f6f33Derek Sollenberger    // can be updated by other threads without consequence.
316a1e806ed3b2d9e2727d08cc2a3958fce501f6f33Derek Sollenberger    m_atomicSync.lock();
317a1e806ed3b2d9e2727d08cc2a3958fce501f6f33Derek Sollenberger    bool dirty = m_dirty;
3188ad3ab0e47f0d5039e89c1873c178f538ec1b0dfChris Craik    BaseTileTexture* texture = m_backTexture;
31962ee9670dd9beeb9a8f21d8737250c081382e2f5Teng-Hui Zhu    SkRegion dirtyArea = m_dirtyArea;
3203a7a2aa023d51b1806d4063ab0ea5ef7d488556fNicolas Roard    float scale = m_scale;
321be61abb47b98988ca94bd839a1e17c3267365dc9Nicolas Roard    const int x = m_x;
322be61abb47b98988ca94bd839a1e17c3267365dc9Nicolas Roard    const int y = m_y;
3233c131605fca8e29a88fdc4923d86bdc3f40adb2bNicolas Roard    TilePainter* painter = m_painter;
324cf1ae53e7b2853d1148ecd784379f12dffda9d43Nicolas Roard
3253c131605fca8e29a88fdc4923d86bdc3f40adb2bNicolas Roard    if (!dirty || !texture) {
3263c131605fca8e29a88fdc4923d86bdc3f40adb2bNicolas Roard        m_atomicSync.unlock();
32775394f5ee0aac2337cdff1597b4e686e22c52833Nicolas Roard        return;
3283c131605fca8e29a88fdc4923d86bdc3f40adb2bNicolas Roard    }
329f6a40880028cf495025747229c627f42e25acc66Chris Craik    if (m_state != Unpainted) {
330f6a40880028cf495025747229c627f42e25acc66Chris Craik        XLOG("Warning: started painting tile %p, but was at state %d, ft %p bt %p",
331f6a40880028cf495025747229c627f42e25acc66Chris Craik              this, m_state, m_frontTexture, m_backTexture);
332f6a40880028cf495025747229c627f42e25acc66Chris Craik    }
333f6a40880028cf495025747229c627f42e25acc66Chris Craik    m_state = PaintingStarted;
33462ee9670dd9beeb9a8f21d8737250c081382e2f5Teng-Hui Zhu    TextureInfo* textureInfo = texture->getTextureInfo();
3353c131605fca8e29a88fdc4923d86bdc3f40adb2bNicolas Roard    m_atomicSync.unlock();
336a52793c453c1512d0a18d4ae3108a975f998ae45Derek Sollenberger
337a1e806ed3b2d9e2727d08cc2a3958fce501f6f33Derek Sollenberger    // at this point we can safely check the ownership (if the texture got
338a1e806ed3b2d9e2727d08cc2a3958fce501f6f33Derek Sollenberger    // transferred to another BaseTile under us)
3398ad3ab0e47f0d5039e89c1873c178f538ec1b0dfChris Craik    if (texture->owner() != this) {
34075394f5ee0aac2337cdff1597b4e686e22c52833Nicolas Roard        return;
341a5ffb7c279df240a07658953e1bd5df6d0480cb6Nicolas Roard    }
342a5ffb7c279df240a07658953e1bd5df6d0480cb6Nicolas Roard
34367e4aa15702646d5ff50e9524f4e63eb9ed20122Nicolas Roard    unsigned int pictureCount = 0;
34467e4aa15702646d5ff50e9524f4e63eb9ed20122Nicolas Roard
345c7e578330aece3c556ef205365c24676687223e2Derek Sollenberger    // swap out the renderer if necessary
346c7e578330aece3c556ef205365c24676687223e2Derek Sollenberger    BaseRenderer::swapRendererIfNeeded(m_renderer);
347232d0b3572d13d9b4fb1211d9d56252a1ede3ed6Derek Sollenberger    // setup the common renderInfo fields;
348232d0b3572d13d9b4fb1211d9d56252a1ede3ed6Derek Sollenberger    TileRenderInfo renderInfo;
349232d0b3572d13d9b4fb1211d9d56252a1ede3ed6Derek Sollenberger    renderInfo.x = x;
350232d0b3572d13d9b4fb1211d9d56252a1ede3ed6Derek Sollenberger    renderInfo.y = y;
351232d0b3572d13d9b4fb1211d9d56252a1ede3ed6Derek Sollenberger    renderInfo.scale = scale;
352232d0b3572d13d9b4fb1211d9d56252a1ede3ed6Derek Sollenberger    renderInfo.tileSize = texture->getSize();
3533c131605fca8e29a88fdc4923d86bdc3f40adb2bNicolas Roard    renderInfo.tilePainter = painter;
3543c131605fca8e29a88fdc4923d86bdc3f40adb2bNicolas Roard    renderInfo.baseTile = this;
355232d0b3572d13d9b4fb1211d9d56252a1ede3ed6Derek Sollenberger    renderInfo.textureInfo = textureInfo;
356232d0b3572d13d9b4fb1211d9d56252a1ede3ed6Derek Sollenberger
357232d0b3572d13d9b4fb1211d9d56252a1ede3ed6Derek Sollenberger    const float tileWidth = renderInfo.tileSize.width();
358232d0b3572d13d9b4fb1211d9d56252a1ede3ed6Derek Sollenberger    const float tileHeight = renderInfo.tileSize.height();
359232d0b3572d13d9b4fb1211d9d56252a1ede3ed6Derek Sollenberger
36067e4aa15702646d5ff50e9524f4e63eb9ed20122Nicolas Roard    SkRegion::Iterator cliperator(dirtyArea);
36167e4aa15702646d5ff50e9524f4e63eb9ed20122Nicolas Roard
36267e4aa15702646d5ff50e9524f4e63eb9ed20122Nicolas Roard    bool fullRepaint = false;
363f85cf343a02e85633e6b68c7f5db3c033b780607Teng-Hui Zhu
36462ee9670dd9beeb9a8f21d8737250c081382e2f5Teng-Hui Zhu    if (m_fullRepaint
365f85cf343a02e85633e6b68c7f5db3c033b780607Teng-Hui Zhu        || textureInfo->m_width != tileWidth
366fa807bd31774157959640810e564fbe64338e8e3Nicolas Roard        || textureInfo->m_height != tileHeight) {
36767e4aa15702646d5ff50e9524f4e63eb9ed20122Nicolas Roard        fullRepaint = true;
368fca6a67b130c1f97d366460af412ec6e6de14834Derek Sollenberger    }
36967e4aa15702646d5ff50e9524f4e63eb9ed20122Nicolas Roard
370c048426c23be795d3bf870e47429167b4157a2d6Nicolas Roard    // For now, only do full repaint
37162ee9670dd9beeb9a8f21d8737250c081382e2f5Teng-Hui Zhu    fullRepaint = true;
3725d77d7f575389ee1f20a394c635928c2e75667c7Nicolas Roard
373c048426c23be795d3bf870e47429167b4157a2d6Nicolas Roard    if (!fullRepaint) {
374c048426c23be795d3bf870e47429167b4157a2d6Nicolas Roard        // compute the partial inval area
375c048426c23be795d3bf870e47429167b4157a2d6Nicolas Roard        SkIRect totalRect;
376c048426c23be795d3bf870e47429167b4157a2d6Nicolas Roard        totalRect.set(0, 0, 0, 0);
377c048426c23be795d3bf870e47429167b4157a2d6Nicolas Roard        float tileSurface = tileWidth * tileHeight;
378c048426c23be795d3bf870e47429167b4157a2d6Nicolas Roard        float tileSurfaceCap = MAX_INVAL_AREA * tileSurface;
379c048426c23be795d3bf870e47429167b4157a2d6Nicolas Roard
380c048426c23be795d3bf870e47429167b4157a2d6Nicolas Roard        // We join all the invals in the same tile for now
381c048426c23be795d3bf870e47429167b4157a2d6Nicolas Roard        while (!fullRepaint && !cliperator.done()) {
382c048426c23be795d3bf870e47429167b4157a2d6Nicolas Roard            SkRect realTileRect;
383c048426c23be795d3bf870e47429167b4157a2d6Nicolas Roard            SkRect dirtyRect;
384c048426c23be795d3bf870e47429167b4157a2d6Nicolas Roard            dirtyRect.set(cliperator.rect());
385c048426c23be795d3bf870e47429167b4157a2d6Nicolas Roard            bool intersect = intersectWithRect(x, y, tileWidth, tileHeight,
386c048426c23be795d3bf870e47429167b4157a2d6Nicolas Roard                                               scale, dirtyRect, realTileRect);
387c048426c23be795d3bf870e47429167b4157a2d6Nicolas Roard            if (intersect) {
388c048426c23be795d3bf870e47429167b4157a2d6Nicolas Roard                // initialize finalRealRect to the rounded values of realTileRect
389c048426c23be795d3bf870e47429167b4157a2d6Nicolas Roard                SkIRect finalRealRect;
390c048426c23be795d3bf870e47429167b4157a2d6Nicolas Roard                realTileRect.roundOut(&finalRealRect);
391c048426c23be795d3bf870e47429167b4157a2d6Nicolas Roard
392c048426c23be795d3bf870e47429167b4157a2d6Nicolas Roard                // stash the int values of the current width and height
393c048426c23be795d3bf870e47429167b4157a2d6Nicolas Roard                const int iWidth = finalRealRect.width();
394c048426c23be795d3bf870e47429167b4157a2d6Nicolas Roard                const int iHeight = finalRealRect.height();
395c048426c23be795d3bf870e47429167b4157a2d6Nicolas Roard
396c048426c23be795d3bf870e47429167b4157a2d6Nicolas Roard                if (iWidth == tileWidth || iHeight == tileHeight) {
397c048426c23be795d3bf870e47429167b4157a2d6Nicolas Roard                    fullRepaint = true;
398c048426c23be795d3bf870e47429167b4157a2d6Nicolas Roard                    break;
399c048426c23be795d3bf870e47429167b4157a2d6Nicolas Roard                }
400c048426c23be795d3bf870e47429167b4157a2d6Nicolas Roard
401c048426c23be795d3bf870e47429167b4157a2d6Nicolas Roard                // translate the rect into tile space coordinates
402c048426c23be795d3bf870e47429167b4157a2d6Nicolas Roard                finalRealRect.fLeft = finalRealRect.fLeft % static_cast<int>(tileWidth);
403c048426c23be795d3bf870e47429167b4157a2d6Nicolas Roard                finalRealRect.fTop = finalRealRect.fTop % static_cast<int>(tileHeight);
404c048426c23be795d3bf870e47429167b4157a2d6Nicolas Roard                finalRealRect.fRight = finalRealRect.fLeft + iWidth;
405c048426c23be795d3bf870e47429167b4157a2d6Nicolas Roard                finalRealRect.fBottom = finalRealRect.fTop + iHeight;
406c048426c23be795d3bf870e47429167b4157a2d6Nicolas Roard                totalRect.join(finalRealRect);
407c048426c23be795d3bf870e47429167b4157a2d6Nicolas Roard                float repaintSurface = totalRect.width() * totalRect.height();
408c048426c23be795d3bf870e47429167b4157a2d6Nicolas Roard
409c048426c23be795d3bf870e47429167b4157a2d6Nicolas Roard                if (repaintSurface > tileSurfaceCap) {
410c048426c23be795d3bf870e47429167b4157a2d6Nicolas Roard                    fullRepaint = true;
411c048426c23be795d3bf870e47429167b4157a2d6Nicolas Roard                    break;
412c048426c23be795d3bf870e47429167b4157a2d6Nicolas Roard                }
413fca6a67b130c1f97d366460af412ec6e6de14834Derek Sollenberger            }
414fca6a67b130c1f97d366460af412ec6e6de14834Derek Sollenberger
415c048426c23be795d3bf870e47429167b4157a2d6Nicolas Roard            cliperator.next();
416c048426c23be795d3bf870e47429167b4157a2d6Nicolas Roard        }
41767e4aa15702646d5ff50e9524f4e63eb9ed20122Nicolas Roard
418c048426c23be795d3bf870e47429167b4157a2d6Nicolas Roard        if (!fullRepaint) {
419c048426c23be795d3bf870e47429167b4157a2d6Nicolas Roard            renderInfo.invalRect = &totalRect;
420232d0b3572d13d9b4fb1211d9d56252a1ede3ed6Derek Sollenberger            renderInfo.measurePerf = false;
4218dfdf8aa25b250ed3b8c0a443cf1cbaf9bd12c5bDerek Sollenberger            pictureCount = m_renderer->renderTiledContent(renderInfo);
42267e4aa15702646d5ff50e9524f4e63eb9ed20122Nicolas Roard        }
42367e4aa15702646d5ff50e9524f4e63eb9ed20122Nicolas Roard    }
424fca6a67b130c1f97d366460af412ec6e6de14834Derek Sollenberger
425fa807bd31774157959640810e564fbe64338e8e3Nicolas Roard    // Do a full repaint if needed
426fca6a67b130c1f97d366460af412ec6e6de14834Derek Sollenberger    if (fullRepaint) {
427c048426c23be795d3bf870e47429167b4157a2d6Nicolas Roard        renderInfo.invalRect = 0;
428232d0b3572d13d9b4fb1211d9d56252a1ede3ed6Derek Sollenberger        renderInfo.measurePerf = TilesManager::instance()->getShowVisualIndicator();
4298dfdf8aa25b250ed3b8c0a443cf1cbaf9bd12c5bDerek Sollenberger        pictureCount = m_renderer->renderTiledContent(renderInfo);
430fca6a67b130c1f97d366460af412ec6e6de14834Derek Sollenberger    }
431fca6a67b130c1f97d366460af412ec6e6de14834Derek Sollenberger
43267e4aa15702646d5ff50e9524f4e63eb9ed20122Nicolas Roard    m_atomicSync.lock();
4337c554a61cb935660cdc86905d040c781b490150fTeng-Hui Zhu
4348ad3ab0e47f0d5039e89c1873c178f538ec1b0dfChris Craik    if (texture == m_backTexture) {
435fa807bd31774157959640810e564fbe64338e8e3Nicolas Roard        m_isTexturePainted = true;
436a5ffb7c279df240a07658953e1bd5df6d0480cb6Nicolas Roard
4375ba4a087b9212ca9ae083f015637f417199d85ccJohn Reck        // set the fullrepaint flags
43862ee9670dd9beeb9a8f21d8737250c081382e2f5Teng-Hui Zhu        m_fullRepaint = false;
43967e4aa15702646d5ff50e9524f4e63eb9ed20122Nicolas Roard
4405ba4a087b9212ca9ae083f015637f417199d85ccJohn Reck        // The various checks to see if we are still dirty...
44167e4aa15702646d5ff50e9524f4e63eb9ed20122Nicolas Roard
4425ba4a087b9212ca9ae083f015637f417199d85ccJohn Reck        m_dirty = false;
44367e4aa15702646d5ff50e9524f4e63eb9ed20122Nicolas Roard
4445ba4a087b9212ca9ae083f015637f417199d85ccJohn Reck        if (m_scale != scale)
4455ba4a087b9212ca9ae083f015637f417199d85ccJohn Reck            m_dirty = true;
44667e4aa15702646d5ff50e9524f4e63eb9ed20122Nicolas Roard
447fca6a67b130c1f97d366460af412ec6e6de14834Derek Sollenberger        if (fullRepaint)
44862ee9670dd9beeb9a8f21d8737250c081382e2f5Teng-Hui Zhu            m_dirtyArea.setEmpty();
449fca6a67b130c1f97d366460af412ec6e6de14834Derek Sollenberger        else
45062ee9670dd9beeb9a8f21d8737250c081382e2f5Teng-Hui Zhu            m_dirtyArea.op(dirtyArea, SkRegion::kDifference_Op);
45167e4aa15702646d5ff50e9524f4e63eb9ed20122Nicolas Roard
45262ee9670dd9beeb9a8f21d8737250c081382e2f5Teng-Hui Zhu        if (!m_dirtyArea.isEmpty())
4535ba4a087b9212ca9ae083f015637f417199d85ccJohn Reck            m_dirty = true;
454c15781f45f0d19a925be7fd73bd10c318562db70Nicolas Roard
455808dc42f1e6a574778bc9e8bd41beb7bd9aef06fChris Craik        XLOG("painted tile %p (%d, %d), texture %p, dirty=%d", this, x, y, texture, m_dirty);
456e733717c7b60d2ccfee9c47af4659ffb8e70dd73Chris Craik
457f6a40880028cf495025747229c627f42e25acc66Chris Craik        validatePaint();
458f6a40880028cf495025747229c627f42e25acc66Chris Craik    } else {
459f6a40880028cf495025747229c627f42e25acc66Chris Craik        XLOG("tile %p no longer owns texture %p, m_state %d. ft %p bt %p",
460f6a40880028cf495025747229c627f42e25acc66Chris Craik             this, texture, m_state, m_frontTexture, m_backTexture);
4615ba4a087b9212ca9ae083f015637f417199d85ccJohn Reck    }
46267e4aa15702646d5ff50e9524f4e63eb9ed20122Nicolas Roard
46367e4aa15702646d5ff50e9524f4e63eb9ed20122Nicolas Roard    m_atomicSync.unlock();
46467e4aa15702646d5ff50e9524f4e63eb9ed20122Nicolas Roard}
46567e4aa15702646d5ff50e9524f4e63eb9ed20122Nicolas Roard
4668ad3ab0e47f0d5039e89c1873c178f538ec1b0dfChris Craikvoid BaseTile::discardTextures() {
4678ad3ab0e47f0d5039e89c1873c178f538ec1b0dfChris Craik    android::AutoMutex lock(m_atomicSync);
468959c08a729d39539327aeb634dbce69524e7b678Chris Craik    XLOG("%p discarding bt %p, ft %p",
469959c08a729d39539327aeb634dbce69524e7b678Chris Craik         this, m_backTexture, m_frontTexture);
4708ad3ab0e47f0d5039e89c1873c178f538ec1b0dfChris Craik    if (m_frontTexture) {
4718ad3ab0e47f0d5039e89c1873c178f538ec1b0dfChris Craik        m_frontTexture->release(this);
4728ad3ab0e47f0d5039e89c1873c178f538ec1b0dfChris Craik        m_frontTexture = 0;
4738ad3ab0e47f0d5039e89c1873c178f538ec1b0dfChris Craik    }
4748ad3ab0e47f0d5039e89c1873c178f538ec1b0dfChris Craik    if (m_backTexture) {
4758ad3ab0e47f0d5039e89c1873c178f538ec1b0dfChris Craik        m_backTexture->release(this);
4768ad3ab0e47f0d5039e89c1873c178f538ec1b0dfChris Craik        m_backTexture = 0;
4778ad3ab0e47f0d5039e89c1873c178f538ec1b0dfChris Craik    }
47862ee9670dd9beeb9a8f21d8737250c081382e2f5Teng-Hui Zhu    m_dirtyArea.setEmpty();
47962ee9670dd9beeb9a8f21d8737250c081382e2f5Teng-Hui Zhu    m_fullRepaint = true;
48062ee9670dd9beeb9a8f21d8737250c081382e2f5Teng-Hui Zhu
4818ad3ab0e47f0d5039e89c1873c178f538ec1b0dfChris Craik    m_dirty = true;
482f6a40880028cf495025747229c627f42e25acc66Chris Craik    m_state = Unpainted;
4838ad3ab0e47f0d5039e89c1873c178f538ec1b0dfChris Craik}
4848ad3ab0e47f0d5039e89c1873c178f538ec1b0dfChris Craik
4853a819aac70dd26f675644f6a35b13be5fb3de2f1Chris Craikvoid BaseTile::discardBackTexture() {
4863a819aac70dd26f675644f6a35b13be5fb3de2f1Chris Craik    android::AutoMutex lock(m_atomicSync);
4873a819aac70dd26f675644f6a35b13be5fb3de2f1Chris Craik    if (m_backTexture) {
4883a819aac70dd26f675644f6a35b13be5fb3de2f1Chris Craik        m_backTexture->release(this);
4893a819aac70dd26f675644f6a35b13be5fb3de2f1Chris Craik        m_backTexture = 0;
4903a819aac70dd26f675644f6a35b13be5fb3de2f1Chris Craik    }
4913ef9d5cc655b8274860b8d15441201d3e621baf5Chris Craik    m_state = Unpainted;
4923ef9d5cc655b8274860b8d15441201d3e621baf5Chris Craik    m_dirty = true;
4933a819aac70dd26f675644f6a35b13be5fb3de2f1Chris Craik}
4943a819aac70dd26f675644f6a35b13be5fb3de2f1Chris Craik
4958ad3ab0e47f0d5039e89c1873c178f538ec1b0dfChris Craikbool BaseTile::swapTexturesIfNeeded() {
4968ad3ab0e47f0d5039e89c1873c178f538ec1b0dfChris Craik    android::AutoMutex lock(m_atomicSync);
497f6a40880028cf495025747229c627f42e25acc66Chris Craik    if (m_state == ReadyToSwap) {
4988ad3ab0e47f0d5039e89c1873c178f538ec1b0dfChris Craik        // discard old texture and swap the new one in its place
4998ad3ab0e47f0d5039e89c1873c178f538ec1b0dfChris Craik        if (m_frontTexture)
5008ad3ab0e47f0d5039e89c1873c178f538ec1b0dfChris Craik            m_frontTexture->release(this);
5018ad3ab0e47f0d5039e89c1873c178f538ec1b0dfChris Craik
5028ad3ab0e47f0d5039e89c1873c178f538ec1b0dfChris Craik        m_frontTexture = m_backTexture;
5038ad3ab0e47f0d5039e89c1873c178f538ec1b0dfChris Craik        m_backTexture = 0;
504f6a40880028cf495025747229c627f42e25acc66Chris Craik        m_state = UpToDate;
505f6a40880028cf495025747229c627f42e25acc66Chris Craik        XLOG("display texture for %p at %d, %d front is now %p, back is %p",
506f6a40880028cf495025747229c627f42e25acc66Chris Craik             this, m_x, m_y, m_frontTexture, m_backTexture);
507f6a40880028cf495025747229c627f42e25acc66Chris Craik
5088ad3ab0e47f0d5039e89c1873c178f538ec1b0dfChris Craik        return true;
5098ad3ab0e47f0d5039e89c1873c178f538ec1b0dfChris Craik    }
5108ad3ab0e47f0d5039e89c1873c178f538ec1b0dfChris Craik    return false;
5118ad3ab0e47f0d5039e89c1873c178f538ec1b0dfChris Craik}
5128ad3ab0e47f0d5039e89c1873c178f538ec1b0dfChris Craik
513f6a40880028cf495025747229c627f42e25acc66Chris Craikvoid BaseTile::backTextureTransfer() {
514f6a40880028cf495025747229c627f42e25acc66Chris Craik    android::AutoMutex lock(m_atomicSync);
515f6a40880028cf495025747229c627f42e25acc66Chris Craik    if (m_state == PaintingStarted)
516f6a40880028cf495025747229c627f42e25acc66Chris Craik        m_state = TransferredUnvalidated;
517f6a40880028cf495025747229c627f42e25acc66Chris Craik    else if (m_state == ValidatedUntransferred)
518f6a40880028cf495025747229c627f42e25acc66Chris Craik        m_state = ReadyToSwap;
519f6a40880028cf495025747229c627f42e25acc66Chris Craik    else {
520f6a40880028cf495025747229c627f42e25acc66Chris Craik        // shouldn't have transferred a tile in any other state, log
521f6a40880028cf495025747229c627f42e25acc66Chris Craik        XLOG("Note: transferred tile %p at %d %d, state wasn't paintingstarted or validated: %d",
522f6a40880028cf495025747229c627f42e25acc66Chris Craik             this, m_x, m_y, m_state);
523f6a40880028cf495025747229c627f42e25acc66Chris Craik    }
524f6a40880028cf495025747229c627f42e25acc66Chris Craik}
525f6a40880028cf495025747229c627f42e25acc66Chris Craik
526530c83c6351e05a6939ad0b5bc291da073e77b5bChris Craikvoid BaseTile::backTextureTransferFail() {
527530c83c6351e05a6939ad0b5bc291da073e77b5bChris Craik    // transfer failed for some reason, mark dirty so it will (repaint and) be
528530c83c6351e05a6939ad0b5bc291da073e77b5bChris Craik    // retransferred.
529530c83c6351e05a6939ad0b5bc291da073e77b5bChris Craik    android::AutoMutex lock(m_atomicSync);
530530c83c6351e05a6939ad0b5bc291da073e77b5bChris Craik    m_state = Unpainted;
5313ef9d5cc655b8274860b8d15441201d3e621baf5Chris Craik    m_dirty = true;
532530c83c6351e05a6939ad0b5bc291da073e77b5bChris Craik    // whether validatePaint is called before or after, it won't do anything
533530c83c6351e05a6939ad0b5bc291da073e77b5bChris Craik}
534530c83c6351e05a6939ad0b5bc291da073e77b5bChris Craik
535f6a40880028cf495025747229c627f42e25acc66Chris Craikvoid BaseTile::validatePaint() {
536f6a40880028cf495025747229c627f42e25acc66Chris Craik    // ONLY CALL while m_atomicSync is locked (at the end of paintBitmap())
537f6a40880028cf495025747229c627f42e25acc66Chris Craik
538f6a40880028cf495025747229c627f42e25acc66Chris Craik    if (!m_dirty) {
539f6a40880028cf495025747229c627f42e25acc66Chris Craik        // since after the paint, the tile isn't dirty, 'validate' it - this
540f6a40880028cf495025747229c627f42e25acc66Chris Craik        // may happed before or after the transfer queue operation. Only
541f6a40880028cf495025747229c627f42e25acc66Chris Craik        // when both have happened, mark as 'ReadyToSwap'
542f6a40880028cf495025747229c627f42e25acc66Chris Craik        if (m_state == PaintingStarted)
543f6a40880028cf495025747229c627f42e25acc66Chris Craik            m_state = ValidatedUntransferred;
544309ae897e0ad3493fc6acd97a39c631f90580d57Teng-Hui Zhu        else if (m_state == TransferredUnvalidated) {
5458abedfb0681eb18f62137fffde000a9dbb75c4d2Teng-Hui Zhu            // When the backTexture has been marked pureColor, we will skip the
5468abedfb0681eb18f62137fffde000a9dbb75c4d2Teng-Hui Zhu            // transfer and marked as ReadyToSwap, in this case, we don't want
5478abedfb0681eb18f62137fffde000a9dbb75c4d2Teng-Hui Zhu            // to reset m_dirty bit to true.
548f6a40880028cf495025747229c627f42e25acc66Chris Craik            m_state = ReadyToSwap;
5498abedfb0681eb18f62137fffde000a9dbb75c4d2Teng-Hui Zhu        } else {
550f6a40880028cf495025747229c627f42e25acc66Chris Craik            XLOG("Note: validated tile %p at %d %d, state wasn't paintingstarted or transferred %d",
551f6a40880028cf495025747229c627f42e25acc66Chris Craik                  this, m_x, m_y, m_state);
5523ef9d5cc655b8274860b8d15441201d3e621baf5Chris Craik            // failed transferring, in which case mark dirty (since
5533ef9d5cc655b8274860b8d15441201d3e621baf5Chris Craik            // paintBitmap() may have cleared m_dirty)
5543ef9d5cc655b8274860b8d15441201d3e621baf5Chris Craik            m_dirty = true;
555f6a40880028cf495025747229c627f42e25acc66Chris Craik        }
556f6a40880028cf495025747229c627f42e25acc66Chris Craik
557f6a40880028cf495025747229c627f42e25acc66Chris Craik        if (m_deferredDirty) {
558f6a40880028cf495025747229c627f42e25acc66Chris Craik            XLOG("Note: deferred dirty flag set, possibly a missed paint on tile %p", this);
559f6a40880028cf495025747229c627f42e25acc66Chris Craik            m_deferredDirty = false;
560f6a40880028cf495025747229c627f42e25acc66Chris Craik        }
561f6a40880028cf495025747229c627f42e25acc66Chris Craik    } else {
562f6a40880028cf495025747229c627f42e25acc66Chris Craik        XLOG("Note: paint was unsuccessful.");
563f6a40880028cf495025747229c627f42e25acc66Chris Craik        m_state = Unpainted;
564f6a40880028cf495025747229c627f42e25acc66Chris Craik    }
565f6a40880028cf495025747229c627f42e25acc66Chris Craik
566f6a40880028cf495025747229c627f42e25acc66Chris Craik}
567f6a40880028cf495025747229c627f42e25acc66Chris Craik
568a5ffb7c279df240a07658953e1bd5df6d0480cb6Nicolas Roard} // namespace WebCore
569a5ffb7c279df240a07658953e1bd5df6d0480cb6Nicolas Roard
570a5ffb7c279df240a07658953e1bd5df6d0480cb6Nicolas Roard#endif // USE(ACCELERATED_COMPOSITING)
571