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